全部產品
Search
文件中心

Elastic Compute Service:Linux執行個體使用雲助手與在ECS執行個體本地執行命令的差異

更新時間:May 08, 2025

本文介紹Linux執行個體使用雲助手與本地執行命令的差異。

雲助手概述

雲助手Agent作為一個服務運行在ECS執行個體中,直接與阿里雲相關服務端通訊,擷取並執行命令後上報結果,雲助手Agent與使用者使用SSH等方式遠端連線到ECS執行個體上執行命令的通訊鏈路不同,因此使用雲助手與登入ECS執行個體執行命令的結果可能存在差異。關於雲助手的更多資訊,請參見雲助手概述

環境變數存在差異

通過雲助手執行命令時和本地執行時的環境變數存在差異。

差異原因

本地執行:使用遠端連線軟體(例如PuTTY、Xshell等)串連Linux執行個體或通過ECS控制台的VNC遠端連線登入執行個體後,預設進入互動式登入的Shell環境。在這個環境中,Shell解譯器(如/bin/bash)會載入環境配置和初始化相關的開機檔案,例如/etc/profile~/.bash_profile~/.bashrc等。這些開機檔案中通常會包含部分環境變數,例如HOSTNAME

雲助手執行:雲助手在通過Shell執行命令時,啟動的Shell環境不是互動式登入的環境,不會載入/etc/profile~/.bash_profile~/.bashrc等開機檔案,因此,雲助手無法獲得和使用包含在這些開機檔案中定義的環境變數。

所以,當您使用雲助手執行命令時,如果待執行的命令中需要使用雲助手中沒有的環境變數,或者所執行的命令和程式依賴雲助手中沒有的環境變數,則會導致命令執行失敗或者執行結果不符合預期。

說明

您可以通過雲助手或者在執行個體本地使用export命令查看環境中的變數資訊。

解決方案

您可以在雲助手中載入待執行的命令或執行命令調用的程式需要的開機檔案,然後補充缺少的相關變數後,重新執行命令,操作步驟如下:

  1. 使用雲助手檢查命令或程式使用的變數是否存在。雲助手建立命令的操作,請參見建立命令

    根據Shell環境中的判斷命令和變數不存在時的替換邏輯,檢查需要使用的變數是否不存在並進行相應處理的命令模板如下:

    if [ -z "${<依賴的變數名稱>+x}" ]; then
      <依賴變數不存在時的處理動作...>
    fi

    $TERM變數為例,雲助手命令如下:

    #!/bin/sh
    if [ -z "${TERM+x}" ]; then
      echo "\$TERM is not set when script executed via cloud assistant"
    else
      echo "\$TERM is set to '${NOT_SET_VARAIABLE}'"
    fi

    如果命令回顯為已設定的$TERM is not set when script executed via cloud assistant,則$TERM變數不存在。

  2. 在命令中載入環境配置和初始化相關的開機檔案(例如/etc/profile~/.bash_profile~/.bashrc等檔案)。

    • 方法一:在命令中明確式載入開機檔案。

      在Shell指令碼的前面通過 .命令或者Bash解譯器特有的source命令載入指定的環境配置和初始化相關的開機檔案,無需單獨處理每個不存在的變數,樣本如下:

      • .命令:

        #!/bin/sh
        . /etc/profile
      • source命令

        #!/bin/bash
        source $HOME/.bashrc
    • 方法二:在命令開頭的#!語句中,使用參數指定Shell解譯器載入開機檔案。

      說明

      如果您的命令的輸出內容下一步將會被解析和處理,則不推薦本方法。

      如果不希望在命令前面寫入過多的載入開機檔案的語句,而是希望啟用Shell解譯器的互動模式和登入模式,由Shell解譯器自身來載入所依賴的開機檔案,那麼可以使用Shell解譯器的-i參數啟用互動模式、使用-l參數啟用登入模式。兩個參數合并為-il,可通過類似於SSH登入的方式啟用Shell解譯器的互動登入模式,命令如下:

      #!/bin/sh -il

      如果使用Bash解譯器,則可以在命令開頭指定#!/bin/bash -il,具體參數請參考所使用的Shell解譯器的文檔。但是,指定-i參數啟用Shell互動模式時,Shell解譯器會希望並檢測標準輸入stdin為一個互動終端輸入裝置,從而提供任務控制等互動式功能。但云助手在執行命令時標準輸入stdin為空白裝置/dev/null,因此Shell解譯器會檢測失敗並報告相應的錯誤,常見錯誤樣本如下:

      sh: cannot set terminal process group (-1): Inappropriate ioctl for device
      sh: no job control in this shell

      /usr/local/share/aliyun-assist/work/script/t-xx.sh: 0: /usr/local/share/aliyun-assist/work/script/t-hz02vmfqb9vxxq8.sh: can't access tty; job control turned off
      stdin: is not a tty

命令執行結果差異

使用雲助手和本地執行ulimit -n命令的結果不一致,雲助手輸出結果為1024,本地執行輸出結果為65535。

差異原因

Linux公用鏡像中的/etc/security/limits.conf資源限制檔案用於設定系統登入使用者的資源限制,在ECS執行個體本地執行cat /etc/security/limits.conf命令,可以開啟的檔案描述符最大數量為65535。因此,在ECS執行個體本地執行ulimit -n命令時,輸出結果為65535。

[root@localhost ~]# cat /etc/security/limits.conf

root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535

[root@localhost ~]# ulimit -n
65535

通過雲助手執行ulimit -n命令時,/etc/security/limits.conf資源限制檔案對系統服務無限制效果。雲助手服務進程由運行在系統服務上的init引導啟動,該進程開啟的檔案描述符最大數量為1024。因此,雲助手執行ulimit -n時,輸出結果為1024。

在ECS執行個體本地執行cat /proc/雲助手進程PID/limits命令,可以查看雲助手服務進程的資源限制情況。

[root@localhost ~]# cat /proc/$(pid of aliyun-service)/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        unlimited            unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             30546                30546                processes
Max open files            1024                 262144               files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       30546                30546                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

解決方案

在ECS執行個體上將雲助手服務的資源限制設定為65535,設定方式與系統啟動模式有關。

  1. 查詢ECS執行個體系統啟動模式。

    1. 遠端連線Linux執行個體。

      具體操作,請參見ECS遠端連線方式概述

    2. 執行如下命令,查看系統啟動模式。

      • systemd

        strings $(which init) |grep "systemd"

        如果命令回顯中輸出systemd相關資訊,則系統啟動模式為systemd。

      • upstart

        strings $(which init) | grep "upstart"

        如果命令回顯中輸出upstart相關資訊,則系統啟動模式為upstart。

      • sysvinit

        strings $(which init) | grep "sysvinit"

        如果命令回顯中輸出sysvinit相關資訊,則系統啟動模式為sysvinit。

  2. 設定雲助手服務資源限制。

    根據系統啟動模式不同,設定雲助手服務資源限制的操作方法不同。

    systemd啟動模式

    1. 設定所有服務資源限制

      1. 遠端連線Linux執行個體。

        具體操作,請參見ECS遠端連線方式概述

      2. 執行如下命令,修改/etc/systemd/system.conf設定檔,在Manager參數中增加DefaultLimitNOFILE=65535欄位。

        vim /etc/systemd/system.conf
        
        [Manager]
        DefaultLimitNOFILE=65535
      3. 執行如下命令,重新運行systemd管理器並重新讀取系統設定檔。

        systemctl  daemon-reexec
      4. 執行如下命令,重啟雲助手服務。

        systemctl restart aliyun.service

        雲助手服務重啟完畢,雲助手服務的資源限制被設定為65535。

    2. 設定雲助手服務資源限制

      1. 遠端連線Linux執行個體。

        具體操作,請參見ECS遠端連線方式概述

      2. 執行如下命令,在雲助手服務的service設定檔Service參數中增加LimitNOFILE=65535欄位。

        [root@localhost ~]# vim /etc/systemd/system/aliyun.service
        ....
        [Service]
        LimitNOFILE=65535
        ....
      3. 執行如下命令,重新載入系統設定檔。

        [root@localhost ~]# systemctl daemon-reload
      4. 執行如下命令,重啟雲助手服務。

        [root@localhost ~]# systemctl restart aliyun

        雲助手服務重啟完畢,雲助手服務的資源限制被設定為65535。

    非systemd啟動模式

    • 修改雲助手的啟動指令碼

      1. 遠端連線Linux執行個體。

        具體操作,請參見ECS遠端連線方式概述

      2. 執行如下命令,在雲助手執行進程前添加ulimit -n 65535欄位。

         [root@localhost ~]# vim /etc/init.d/aliyun-service
        
        ..................
         start() {
            if [ -f $service_lock ]; then
                ps aux | grep "$start_cmd" | grep -v grep 1>/dev/null 2>&1
                if [ $? -eq 0 ]; then
                    echo "$aliyun_service_name is already started!" 1>/dev/null 2>&1
                    return 0
                else
                    rm -rf $service_lock
                fi
            fi
            ulimit -n 65535
            $start_cmd
        
            ### Create the lock file ###
            touch $service_lock
        }
        ....................
      3. 執行如下命令,重啟雲助手服務。

        [root@localhost ~]# /etc/init.d/aliyun-service restart

        雲助手服務重啟完畢,雲助手服務的資源限制被設定為65535。

    • 修改雲助手的設定檔

      說明

      僅upstart啟動模式的系統支援修改雲助手的設定檔來設定資源限制。

      1. 遠端連線Linux執行個體。

        具體操作,請參見ECS遠端連線方式概述

      2. 執行如下命令,修改雲助手的設定檔中的limit nofile欄位為65535。

        [root@localhost ~]# cat /etc/init/aliyun-service.conf
        description     "Aliyun Assist Tool"
        author          "aliyun.com"
        
        start on runlevel [2345]
        stop on runlevel [!2345]
        
        limit nofile 65535 65535
        
        respawn
        
        exec /usr/sbin/aliyun-service
        post-stop exec sleep 1
        
        [root@localhost ~]# service aliyun-service restart
      3. 執行如下命令,重啟雲助手服務。

        [root@localhost ~]# service aliyun-service restart

        雲助手服務重啟完畢,雲助手服務的資源限制被設定為65535。

執行結果輸出完整度差異

相比較於ECS執行個體本地執行命令,使用雲助手執行命令輸出的結果不完整。

差異原因

雲助手執行命令輸出結果大小限制為16 KB,因此,當命令執行結果的檔案大小超過16 KB時,使用雲助手執行命令輸出的結果會不完整。

解決方案

建議您將雲助手命令的輸出結果儲存到本地日誌或儲存到OSS中。

命令執行是否報錯差異

使用雲助手執行命令時顯示失敗,但在ECS執行個體本地執行時卻沒有報錯。

差異原因

  • 可能原因1:

    使用雲助手執行和ECS執行個體本地執行命令,指令碼的退出碼均是最後一條命令的傳回值,如果該值非零,系統就會提示失敗。有的命令在ECS執行個體本地執行雖然退出碼非零,但執行結果中無明顯報錯,使用者會以為命令是執行成功的,此時,使用雲助手執行命令就會提示失敗。

  • 可能原因2:

    雲助手執行命令時,會將命令儲存成指令碼,然後通過sh -c "./script"方式執行命令。ECS執行個體本地執行命令時,使用Bash解譯器執行。由於解譯器差異,可能存在使用雲助手執行命令失敗,但ECS執行個體本地執行正常的情況。例如Sh解譯器不支援進程替換<(cmd)文法而Bash解譯器支援,此時,使用雲助手執行命令就會提示執行失敗。

解決方案

使用雲助手執行命令前,在命令首行增加#!/bin/bash命令,指定使用Bash解譯器。

特定執行個體命令執行差異

在Debian、Ubuntu和UOS執行個體上使用雲助手執行出現語法錯誤,但Debian、Ubuntu和UOS執行個體的本地執行指令碼卻正常。

可能原因

在Debian、Ubuntu和UOS執行個體中,當使用者互動式登入執行個體後,預設分配的Bash環境是/bin/bash,該環境的預設配置被定義在/etc/adduser.conf中。當在非互動式登入環境中執行指令碼且在指令碼中未定義解譯器時,預設是用/bin/sh執行。

在Debian、Ubuntu和UOS執行個體中,/bin/sh被連結到了dash,因此使用雲助手執行命令可能會因為文法不相容導致執行失敗,例如執行Bash特有的source命令或function關鍵字定義函數等,更多資訊,請參見Shell

解決方案

使用雲助手執行命令前,在命令首行增加#!/bin/bash命令,指定使用Bash解譯器。