このトピックでは、Cloud Assistant を使用して Linux インスタンスでリモートでコマンドを実行する場合と、Linux インスタンスでローカルにコマンドを実行する場合の違いについて説明します。
Cloud Assistant
クラウドアシスタントクライアント は、Elastic Compute Service (ECS)インスタンス上でサービスとして実行され、他の Alibaba Cloud サービスと通信し、コマンドを取得して実行し、コマンドの実行結果を報告します。 クラウドアシスタントクライアント を使用して ECS インスタンスでリモートでコマンドを実行することも、SSH 経由など、さまざまな方法で ECS インスタンスに接続してインスタンスでローカルにコマンドを実行することもできます。 これら 2 つのコマンド実行方法は、異なる通信リンクを使用するため、実行結果が異なる場合があります。 Cloud Assistant の詳細については、「概要」をご参照ください。
環境変数の違い
Cloud Assistant を使用して Linux インスタンスでリモートでコマンドを実行する場合と、インスタンスでローカルにコマンドを実行する場合では、環境変数が異なります。
原因
ローカルでコマンドを実行する場合:PuTTY や Xshell などのリモート接続ソフトウェアを使用するか、ECS コンソールで Virtual Network Computing(VNC)を使用して Linux インスタンスに接続すると、デフォルトで対話型シェル環境に移動します。 この環境では、シェルインタープリター(/bin/bash
など)は、/etc/profile、~/.bash_profile、~/.bashrc などの環境構成関連および初期化関連のスタートアップファイルを読み込みます。 ほとんどの場合、これらのファイルには HOSTNAME
など、いくつかの環境変数が含まれています。
Cloud Assistant を使用してリモートでコマンドを実行する場合:Cloud Assistant がシェルインタープリターを使用してコマンドを実行する場合、シェルインタープリターが /etc/profile、~/.bash_profile、~/.bashrc などのスタートアップファイルを読み込まない、非対話型シェル環境が起動されます。 その結果、Cloud Assistant はスタートアップファイルで定義されている環境変数を取得または使用できません。
Cloud Assistant を使用してコマンドを実行する場合、コマンドまたはコマンドによって呼び出されるプログラムが Cloud Assistant で定義されていない環境変数に依存している場合、コマンドは期待どおりに実行されないか、期待される実行結果が生成されません。
Cloud Assistant を使用してリモートで、または Linux インスタンスでローカルに export
コマンドを実行して、現在の環境で使用可能な変数を表示できます。
解決策
Cloud Assistant で、必要なスタートアップファイルを読み込み、コマンドまたは関連プログラムが依存する変数をファイルに追加します。 その後、Cloud Assistant を使用してコマンドを再実行します。
コマンドまたは関連プログラムの依存変数が Cloud Assistant で定義されているかどうかを確認します。
Cloud Assistant コマンドの作成方法については、「コマンドの作成」をご参照ください。
次のコマンドを実行して、変数が定義されているかどうかを確認し、変数が存在しない場合は特定のアクションを実行します。
if [ -z "${<Dependency variable name>+x}" ]; then <Action to take if the dependency variable does not exist...> fi
次の Cloud Assistant コマンドの例では、$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 変数は存在しません。次のいずれかの方法を使用して、/etc/profile、~/.bash_profile、~/.bashrc などの環境構成関連および初期化関連のスタートアップファイルをコマンドに読み込みます。
方法 1:スタートアップファイルをコマンドに明示的に読み込みます。
シェルスクリプトの先頭に
.
コマンドまたは Bash 固有のsource
コマンドを配置して、指定された環境構成関連および初期化関連のスタートアップファイルを読み込みます。 これにより、存在しない各変数を処理する必要がなくなります。 コマンドの例:.
コマンド:#!/bin/sh . /etc/profile
source
コマンド:#!/bin/bash source $HOME/.bashrc
方法 2:コマンドの先頭にある
#!
記号で始まる行で、パラメーターを使用してスタートアップファイルを読み込むシェルインタープリターを指定します。説明コマンド出力を解析および処理する必要がある場合は、この方法を使用しないことをお勧めします。
コマンドの先頭に文を追加したくないが、シェルインタープリターの対話モードとログインモードを有効にして必要なスタートアップファイルを読み込みたい場合は、
-i
パラメーターを指定して対話モードを有効にし、-I
パラメーターを指定してシェルインタープリターのログインモードを有効にします。 これらのパラメーターは組み合わされて-iI
パラメーターになります。 次のコマンドを実行して、SSH ログインと同様に、シェルインタープリターの対話型ログインモードを有効にします。#!/bin/sh -il
Bash インタープリターを使用する場合は、コマンドの先頭に
#!/bin/bash -il
を追加できます。 パラメーターの詳細については、使用するシェルインタープリターに関するドキュメントをご参照ください。-i
パラメーターを指定して対話モードを有効にすると、シェルインタープリターは、標準入力(stdin)デバイスが対話型デバイスであることを確認してから、タスク制御などの対話機能を提供します。 Cloud Assistant を使用してコマンドを実行する場合、stdin デバイスはヌルデバイスであり、/dev/null
と記述されます。 その結果、stdin デバイスチェックは失敗し、シェルインタープリターは次のエラーを報告します。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
実行結果の違い
Cloud Assistant を使用してインスタンスでリモートでコマンドを実行する場合と、インスタンスでローカルにコマンドを実行する場合では、実行結果が異なります。 たとえば、Cloud Assistant を使用して Linux インスタンスでリモートでコマンドを実行すると 1024 が返され、インスタンスでローカルにコマンドを実行すると 65535 が返されます。
原因
Linux パブリックイメージの /etc/security/limits.conf
ファイルには、ログインしているユーザーのリソース制限が指定されています。 Linux インスタンスでローカルに cat /etc/security/limits.conf
コマンドを実行してファイルを表示すると、許可されるオープンファイル記述子(nofile)の最大数は 65535 に設定されています。 この場合、インスタンスでローカルに 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
Cloud Assistant を使用して ulimit -n
コマンドを実行する場合、システムサービスは /etc/security/limits.conf
ファイルで指定された制限の対象になりません。 Cloud Assistant サービスプロセスは、システムサービスの最上位で実行される init プログラムによって起動時に開始されます。 サービスプロセスでは、最大 1,024 個のオープンファイル記述子が許可されます。 この場合、Cloud Assistant を使用して Linux インスタンスでリモートで ulimit -n
コマンドを実行すると、コマンド出力は 1024 になります。
Linux インスタンスでローカルに cat /proc/<Cloud Assistant PID>/limits
コマンドを実行して、Cloud Assistant サービスプロセスのリソース制限を表示できます。
[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
解決策
Linux インスタンスでは、システムの起動方法に基づいて、Cloud Assistant のリソース制限を 65535 に設定できます。
ECS インスタンスのシステム起動方法を確認します。
Linux インスタンスに接続します。
詳細については、「ECS インスタンスへの接続方法」をご参照ください。
次のコマンドを実行して、システム起動方法を確認します。
systemd
strings $(which init) |grep "systemd"
コマンド出力に systemd が表示された場合、システム起動方法は systemd です。
upstart
strings $(which init) | grep "upstart"
コマンド出力に upstart が表示された場合、システム起動方法は upstart です。
sysvinit
strings $(which init) | grep "sysvinit"
コマンド出力に sysvinit が表示された場合、システム起動方法は sysvinit です。
Cloud Assistant のリソース制限を構成します。
インスタンスのシステム起動方法に基づいて、Linux インスタンスで Cloud Assistant のリソース制限を構成します。
systemd 起動方法
すべてのサービスのリソース制限を構成する
Linux インスタンスに接続します。
詳細については、「ECS インスタンスへの接続方法」をご参照ください。
次のコマンドを実行して、
DefaultLimitNOFILE
Manager
/etc/systemd/system.conf 構成ファイルの パラメーターに フィールドを追加し、フィールドを 65535 に設定します。vim /etc/systemd/system.conf [Manager] DefaultLimitNOFILE=65535
次のコマンドを実行して、systemd マネージャーを再実行し、システム構成ファイルを再読み込みします。
systemctl daemon-reexec
次のコマンドを実行して、Cloud Assistant を再起動します。
systemctl restart aliyun.service
Cloud Assistant を再起動すると、Cloud Assistant のリソース制限は 65535 に設定されます。
Cloud Assistant のリソース制限を構成する
Linux インスタンスに接続します。
詳細については、「ECS インスタンスに接続する方法」をご参照ください。
次のコマンドを実行して、Cloud Assistant の
LimitNOFILE
Service
service 構成ファイルの パラメーターに フィールドを追加し、フィールドを 65535 に設定します。[root@localhost ~]# vim /etc/systemd/system/aliyun.service .... [Service] LimitNOFILE=65535 ....
次のコマンドを実行して、システム構成ファイルを再読み込みします。
[root@localhost ~]# systemctl daemon-reload
次のコマンドを実行して、Cloud Assistant を再起動します。
[root@localhost ~]# systemctl restart aliyun
Cloud Assistant を再起動すると、Cloud Assistant のリソース制限は 65535 に設定されます。
systemd 以外の起動方法
Cloud Assistant 起動スクリプトを変更する
Linux インスタンスに接続します。
詳細については、「ECS インスタンスへの接続方法」をご参照ください。
次のコマンドを実行して、Cloud Assistant プロセスファイルの先頭に
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 } ....................
次のコマンドを実行して、Cloud Assistant を再起動します。
[root@localhost ~]# /etc/init.d/aliyun-service restart
Cloud Assistant を再起動すると、Cloud Assistant のリソース制限は 65535 に設定されます。
Cloud Assistant 構成ファイルを変更する
説明Cloud Assistant 構成ファイルを変更してリソース制限を構成できるのは、システム起動方法が upstart の場合のみです。
Linux インスタンスに接続します。
詳細については、「ECS インスタンスに接続する方法」をご参照ください。
次のコマンドを実行して、Cloud Assistant 構成ファイルの
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
次のコマンドを実行して、Cloud Assistant を再起動します。
[root@localhost ~]# service aliyun-service restart
Cloud Assistant を再起動すると、Cloud Assistant のリソース制限は 65535 に設定されます。
コマンド出力の完全性の違い
ECS インスタンスでローカルにコマンドを実行すると、完全なコマンド出力が返されます。 一方、Cloud Assistant を使用してインスタンスでリモートでコマンドを実行すると、不完全なコマンド出力が返されます。
原因
Cloud Assistant のコマンド出力サイズは 16 KB に制限されています。 Cloud Assistant を使用して ECS インスタンスでリモートでコマンドを実行し、コマンド出力のサイズが 16 KB を超える場合、不完全なコマンド出力が返されます。
解決策
Cloud Assistant コマンド出力をローカルログまたは Object Storage Service (OSS) に保存することをお勧めします。
コマンド実行中にエラーが報告されるかどうかの違い
Cloud Assistant を使用して ECS インスタンスでリモートでコマンドを実行すると失敗し、エラーが報告されますが、インスタンスでローカルにコマンドを実行すると、エラーは報告されずに実行できます。
原因
考えられる原因 1:
Cloud Assistant を使用して ECS インスタンスでリモートでコマンドを実行する場合、またはインスタンスでローカルにコマンドを実行する場合、コマンドスクリプトの終了コードは、スクリプトに含まれる最後のコマンドによって返される終了コードです。 終了コードがゼロでない場合、コマンドの実行に失敗したことを示すエラーが返されます。 一部のコマンドは、ECS インスタンスでローカルに実行されたときに、エラーのないコマンド出力とゼロ以外の終了コードを返します。 Cloud Assistant を使用して ECS インスタンスでリモートでこのようなコマンドを実行すると、インスタンスでリモートでコマンドを実行できなかったことを示すエラーが返されます。
考えられる原因 2:
Cloud Assistant を使用して ECS インスタンスでリモートでコマンドを実行する場合、Cloud Assistant はコマンドをスクリプトとして保存し、
sh -c "./<Script name>"
を使用して sh インタープリターでコマンドを実行します。 ECS インスタンスでローカルにコマンドを実行する場合、コマンドは Bash インタープリターで実行されます。 sh インタープリターは Bash インタープリターとは異なります。 たとえば、sh インタープリターはプロセス置換構文(<(cmd)
)をサポートしていません。 ただし、Bash インタープリターはこの構文をサポートしています。 その結果、Cloud Assistant を使用して ECS インスタンスでリモートでコマンドを実行できない場合がありますが、ECS インスタンスでローカルに実行できます。
解決策
Cloud Assistant を使用してコマンドを実行する前に、コマンドの最初の行に #!/bin/bash
を追加して、Bash インタープリターを使用します。
特定のインスタンスでコマンドを実行できるかどうかの違い
Debian、Ubuntu、または UOS インスタンスでは、コマンドをローカルに実行して完了できます。 ただし、Cloud Assistant を使用してインスタンスでリモートでコマンドを実行することはできず、構文エラーが報告されます。
原因
Debian、Ubuntu、または UOS インスタンスに対話形式でログインした後、デフォルトで /bin/bash
Bash 環境が割り当てられます。 この環境のデフォルト設定は、/etc/adduser.conf ファイルで定義されています。 Debian、Ubuntu、または UOS インスタンスに非対話形式でログインし、インタープリターが指定されていないスクリプトを実行した後、デフォルトで /bin/sh
が使用されます。
Debian、Ubuntu、または UOS インスタンスでは、/bin/sh
は dash にリンクされています。 その結果、スクリプトに Bash 固有の source
コマンドまたは function
キーワードを使用して定義された関数が含まれているコマンドなど、構文の非互換性のために Cloud Assistant コマンドが実行に失敗する可能性があります。 詳細については、Shell ウェブページをご覧ください。
解決策
Cloud Assistant を使用してコマンドを実行する前に、コマンドの最初の行に #!/bin/bash
を追加して、Bash インタープリターを使用します。