7.8 用SSH在远程主机上运行命令
SSH是一个很有意思的系统管理工具,它能够通过shell登录并控制远程主机。SSH是Secure Shell的缩写。我们可以登录到远程主机上来执行shell命令,就好像是在本地主机上执行这些命令一样。SSH使用加密通道来传输数据。这则攻略介绍了在远程主机上运行命令的各种方法。
7.8.1 新手上路
所有的GNU/Linux发行版都不默认包括SSH,要用软件包管理器安装openssh-server和openssh-client软件包。SSH服务默认在端口22运行。
7.8.2 实战演练
用下面的方法连接运行SSH服务器的远程主机:
- $ ssh username@remote_host
其中
username
是远程主机上的用户;remote_host
可以是域名或IP地址。
例如:
- $ ssh mec@192.168.0.1
- The authenticity of host '192.168.0.1 (192.168.0.1)' can't be established.
- RSA key fingerprint is 2b:b4:90:79:49:0a:f1:b3:8a:db:9f:73:2d:75:d6:f9.
- Are you sure you want to continue connecting (yes/no)? yes
- Warning: Permanently added '192.168.0.1' (RSA) to the list of known hosts.
- Password:
- Last login: Fri Sep 3 05:15:21 2010 from 192.168.0.82
- mec@proxy-1:~$
ssh
采用交互方式询问用户密码,一旦认证成功,将会为用户返回一个shell。
SSH服务器默认在端口22运行。不过,有些运行SSH服务的服务器并不在这个端口运行。针对这种情况,用ssh
命令的 -p port_no
指定端口。
要连接运行在端口422之上的SSH服务器,可以使用:
- $ ssh user@locahost -p 422
你可以在远程主机的shell中执行命令。shell是一个交互式工具,用户可以在其中输入命令并执行它。然而在shell脚本环境中,我们不需要交互式的shell,而是需要将任务自动化。我们需要在远程shell中执行若干命令,然后在本地主机上显示或存储输出内容。每次都要输入密码对于自动化脚本来说显然不实际,因此要对SSH进行自动登录配置。
7.7节讲解了SSH命令。
在运行使用了SSH的自动化脚本之前,要确保配置了自动登录。
要想在远程主机中运行命令,并将命令输出显示在本地shell,使用下面的语法:
- $ ssh user@host 'COMMANDS'
例如:
- $ ssh mec@192.168.0.1 'whoami'
- Password:
- mec
可以输入多条命令,在命令之间以分号进行分隔:
- $ ssh user@host 'command1 ; command2 ; command3'
命令可以通过stdin
发送,而命令输出可以通过stdout
来获取。
语法如下:
- $ ssh user@remote_host "COMMANDS" > stdout.txt 2> errors.txt
COMMANDS
部分应该用引号括起来,以避免分号被本地主机的shell当做定界符。我们也可以通过stdin
将包含管道的命令序列传递给SSH命令:
- $ echo "COMMANDS" | sshuser@remote_host> stdout.txt 2> errors.txt
例如:
- $ ssh mec@192.168.0.1 "echo user: $(whoami);echo OS: $(uname)"
- Password:
- user: slynux
- OS: Linux
在这个例子中,远程主机上执行的命令是:
- echo user: $(whoami);
- echo OS: $(uname)
写成一般化的形式就是:
- COMMANDS="command1; command2; command3"
- $ ssh user@hostname "$COMMANDS"
我们也可以在命令序列中用( )
子shell操作符传递一个更复杂的子shell。
现在,编写一个基于SSH的shell脚本,用来收集一组远程主机的运行时间(uptime)。运行时间是系统加电运行的时间。uptime命令用来显示系统加电后运行了多久。
假设IP_LIST中的所有系统都有一个用户test。
- #!/bin/bash
- #文件名: uptime.sh
- #用途:系统运行时间监视器
- IP_LIST="192.168.0.1 192.168.0.5 192.168.0.9"
- USER="test"
- for IP in $IP_LIST;
- do
- utime=$(ssh $USER@$IP uptime | awk '{ print $3 }' )
- echo $IP uptime: $utime
- done
输出应该是:
- $ ./uptime.sh
- 192.168.0.1 uptime: 1:50,
- 192.168.0.5 uptime: 2:15,
- 192.168.0.9 uptime: 10:15,
7.8.3 补充内容
让我们看看ssh
命令的另一些选项。
- SSH的压缩功能
SSH协议也支持对数据进行压缩传输,当带宽有限时,这一功能很方便。用ssh
命令的选项-C
启用压缩功能:
- $ ssh -C user@hostname COMMANDS
- 将数据重定向至远程shell命令的
stdin
有时候我们需要将一些数据重定向到远程shell命令的stdin
。通过下面的例子看看这如何实现:
- $ echo "text" | ssh user@remote_host 'cat >> list'
或者:
- # 将文件中的数据重定向
- $ ssh user@remote_host 'cat >> list' < file
cat >> list
将通过stdin
接收到的数据添加到文件list中。这条命令是在远程主机上执行的,但数据却是从本地主机传递到远程shell的stdin
的。
7.8.4 参考
7.7节讲解了如何配置自动登录来执行命令而无需提示输入密码。