This topic describes the differences between running commands remotely on Linux instances by using Cloud Assistant and running commands locally on Linux instances.
Cloud Assistant
Cloud Assistant Agent runs as a service on Elastic Compute Service (ECS) instances to communicate with other Alibaba Cloud services, obtain and run commands, and report command execution results. You can use Cloud Assistant Agent to run commands remotely on ECS instances, or connect to ECS instances by using different methods such as over SSH to run commands locally on the instances. These two methods of running commands use different communication links and may have different execution results. For more information about Cloud Assistant, see Overview.
Differences in environment variables
Environment variables differ when you run commands remotely on Linux instances by using Cloud Assistant and when you run commands locally on the instances.
Cause
Running commands locally: When you connect to a Linux instance by using remote connection software such as PuTTY and Xshell or by using Virtual Network Computing (VNC) in the ECS console, you are directed to an interactive shell environment by default. In the environment, the shell interpreter (such as /bin/bash) loads environment configuration-related and initialization-related startup files such as /etc/profile, ~/.bash_profile, and ~/.bashrc. In most cases, these files include some environment variables, such as HOSTNAME.
Running commands remotely by using Cloud Assistant: When Cloud Assistant uses the shell interpreter to run commands, a non-interactive shell environment is started in which the shell interpreter does not load startup files such as /etc/profile, ~/.bash_profile, and ~/.bashrc. As a result, Cloud Assistant cannot obtain or use environment variables defined in the startup files.
When you use Cloud Assistant to run a command, the command cannot be run as expected or does not generate the expected execution results if the command or the programs called by it depend on environment variables not defined in Cloud Assistant.
You can run the export command remotely by using Cloud Assistant or locally on a Linux instance to view variables available in the current environment.
Solution
In Cloud Assistant, load required startup files and add variables that your command or relevant programs depend on to the files. Then, use Cloud Assistant to rerun the command.
Check whether the dependency variables of the command or relevant programs are defined in Cloud Assistant.
For information about how to create a Cloud Assistant command, see Create a command.
Run the following command to check whether a variable is defined and take a specific action if the variable does not exist:
if [ -z "${<Dependency variable name>+x}" ]; then <Action to take if the dependency variable does not exist...> fiIn the following sample Cloud Assistant command, the $TERM variable is used:
#!/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}'" fiIf the
$TERM is not set when script executed via cloud assistanterror message is returned in the command output, the $TERM variable does not exist.Use one of the following methods to load environment configuration-related and initialization-related startup files, such as /etc/profile, ~/.bash_profile, and ~/.bashrc, into the command:
Method 1: Explicitly load startup files into the command.
Place
.commands or Bash-specificsourcecommands in the front of the shell script to load specified environment configuration-related and initialization-related startup files. This eliminates the need to process each nonexistent variable. Sample commands:.command:#!/bin/sh . /etc/profilesourcecommand:#!/bin/bash source $HOME/.bashrc
Method 2: On the line that starts with the
#!symbols at the beginning of the command, use parameters to specify the shell interpreter to load startup files.NoteIf the command output is to be parsed and processed, we recommend that you do not use this method.
If you do not want to add statements at the beginning of the command but you want to enable interactive mode and logon mode for the shell interpreter to load the required startup files, specify the
-iparameter to enable interactive mode and specify the-Iparameter to enable logon mode for the shell interpreter. These parameters are combined to form the-iIparameter. Run the following command to enable interactive logon mode for the shell interpreter, which is similar to SSH logon:#!/bin/sh -ilIf you use the Bash interpreter, you can add
#!/bin/bash -ilat the beginning of the command. For more information about the parameters, see the documentation about the shell interpreter that you use. When you specify the-iparameter to enable interactive mode, the shell interpreter checks that the standard input (stdin) device is an interactive device before the interpreter provides interactive features such as task control. When you use Cloud Assistant to run a command, the stdin device is a null device, which is written as/dev/null. As a result, the stdin device check fails and the shell interpreter reports the following errors:sh: cannot set terminal process group (-1): Inappropriate ioctl for device sh: no job control in this shellOr
/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
Differences in execution results
The execution results differ when you run a command remotely on the instance by using Cloud Assistant and when you run the command locally on the instance. For example, 1024 is returned when you use Cloud Assistant to run a command remotely on a Linux instance, and 65535 is returned when you run the command locally on the instance.
Cause
The /etc/security/limits.conf file in Linux public images specifies resource limits for users that are logged on. When you run the cat /etc/security/limits.conf command locally on a Linux instance to view the file, the maximum allowed number of open file descriptors (nofile) is set to 65535. In this case, the command output is 65535 when you run the ulimit -n command locally on the instance.
[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
65535When you use Cloud Assistant to run the ulimit -n command, system services are not subject to the limits specified in the /etc/security/limits.conf file. The Cloud Assistant service process starts at boot time by the init program that runs on top of system services. The service process allows up to 1,024 open file descriptors. In this case, the command output is 1024 when you use Cloud Assistant to run the ulimit -n command remotely on the Linux instance.
You can run the cat /proc/<Cloud Assistant PID>/limits command locally on your Linux instance to view the resource limits for the Cloud Assistant service process.
[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 usSolution
On your Linux instance, you can set resource limits for Cloud Assistant to 65535 based on the system startup method.
Check the system startup method of your ECS instance.
Connect to the Linux instance.
For more information, see Methods for connecting to an ECS instance.
Run the following commands to check the system startup method.
systemd
strings $(which init) |grep "systemd"If systemd is displayed in the command output, the system startup method is systemd.
upstart
strings $(which init) | grep "upstart"If upstart is displayed in the command output, the system startup method is upstart.
sysvinit
strings $(which init) | grep "sysvinit"If sysvinit is displayed in the command output, the system startup method is sysvinit.
Configure resource limits for Cloud Assistant.
Configure resource limits for Cloud Assistant on a Linux instance based on the system startup method of the instance.
systemd startup method
Configure resource limits for all services
Connect to the Linux instance.
For more information, see Methods for connecting to an ECS instance.
Run the following commands to add the
DefaultLimitNOFILEfield to theManagerparameter in the /etc/systemd/system.conf configuration file and set the field to 65535:vim /etc/systemd/system.conf [Manager] DefaultLimitNOFILE=65535Run the following command to rerun the systemd manager and reread system configuration files:
systemctl daemon-reexecRun the following command to restart Cloud Assistant:
systemctl restart aliyun.serviceAfter you restart Cloud Assistant, the resource limits for Cloud Assistant are set to 65535.
Configure resource limits for Cloud Assistant
Connect to the Linux instance.
For more information, see Methods for connecting to an ECS instance.
Run the following commands to add the
LimitNOFILEfield to theServiceparameter in the service configuration file of Cloud Assistant and set the field to 65535:[root@localhost ~]# vim /etc/systemd/system/aliyun.service .... [Service] LimitNOFILE=65535 ....Run the following command to reload system configuration files:
[root@localhost ~]# systemctl daemon-reloadRun the following command to restart Cloud Assistant:
[root@localhost ~]# systemctl restart aliyunAfter you restart Cloud Assistant, the resource limits for Cloud Assistant are set to 65535.
Non-systemd startup method
Modify the Cloud Assistant startup script
Connect to the Linux instance.
For more information, see Methods for connecting to an ECS instance.
Run the following commands to add the
ulimit -nfield at the beginning of the Cloud Assistant process file and set the field to 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 } ....................Run the following command to restart Cloud Assistant:
[root@localhost ~]# /etc/init.d/aliyun-service restartAfter you restart Cloud Assistant, the resource limits for Cloud Assistant are set to 65535.
Modify the Cloud Assistant configuration file
NoteYou can configure resource limits by modifying the Cloud Assistant configuration file only if the system startup method is upstart.
Connect to the Linux instance.
For more information, see Methods for connecting to an ECS instance.
Run the following commands to set the
limit nofilefield in the Cloud Assistant configuration file to 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 restartRun the following command to restart Cloud Assistant:
[root@localhost ~]# service aliyun-service restartAfter you restart Cloud Assistant, the resource limits for Cloud Assistant are set to 65535.
Differences in command output completeness
A complete command output is returned when you run a command locally on ECS instances. In contrast, an incomplete command output is returned when you use Cloud Assistant to run the command remotely on the instances.
Cause
The command output size is limited to 16 KB for Cloud Assistant. If you use Cloud Assistant to run a command remotely on ECS instances and the command output exceeds 16 KB in size, an incomplete command output is returned.
Solution
We recommend that you store Cloud Assistant command outputs in local logs or Object Storage Service (OSS).
Differences in whether errors are reported during command execution
Commands fail to be run remotely on ECS instances by using Cloud Assistant and errors are reported, but the commands can be run locally on the instances without errors reported.
Causes
Possible cause 1:
When you run a command remotely on ECS instances by using Cloud Assistant or run the command locally on the instances, the exit code of the command script is the exit code returned by the last command that is included in the script. If the exit code is not zero, an error is returned indicating that the command failed to be run. Some commands return error-free command outputs and non-zero exit codes when the commands are run locally on ECS instances. If you use Cloud Assistant to run such a command remotely on an ECS instance, an error is returned indicating that the command failed to be run remotely on the instance.
Possible cause 2:
When you use Cloud Assistant to run a command remotely on ECS instances, Cloud Assistant saves the command as a script and then uses
sh -c "./<Script name>"to run the command in the sh interpreter. When you run a command locally on ECS instances, the command is run in the Bash interpreter. The sh interpreter differs from the Bash interpreter. For example, the sh interpreter does not support the process replacement syntax (<(cmd)). However, the Bash interpreter supports the syntax. As a result, commands may fail to be run remotely on ECS instances by using Cloud Assistant but can be run locally on ECS instances.
Solution
Before you use Cloud Assistant to run a command, add #!/bin/bash to the first line of the command to use the Bash interpreter.
Differences in whether commands can be run on specific instances
Commands can be run locally to completion on Debian, Ubuntu, or UOS instances. However, the commands cannot be run remotely on the instances by using Cloud Assistant and syntax errors are reported.
Cause
After you log on to a Debian, Ubuntu, or UOS instance in an interactive manner, the /bin/bash Bash environment is allocated by default. The default settings of this environment are defined in the /etc/adduser.conf file. After you log on to a Debian, Ubuntu, or UOS instance in a non-interactive manner and run a script in which no interpreters are specified, /bin/sh is used by default.
In Debian, Ubuntu, or UOS instances, /bin/sh is linked to dash. As result, Cloud Assistant commands may fail to be run due to syntax incompatibility, such as commands whose scripts include Bash-specific source commands or functions that are defined by using the function keyword. For more information, visit the Shell webpage.
Solution
Before you use Cloud Assistant to run a command, add #!/bin/bash to the first line of the command to use the Bash interpreter.