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服务器的远程主机:

  1. $ ssh username@remote_host

其中

  • username是远程主机上的用户;

  • remote_host可以是域名或IP地址。

例如:

  1. $ ssh mec@192.168.0.1
  2. The authenticity of host '192.168.0.1 (192.168.0.1)' can't be established.
  3. RSA key fingerprint is 2b:b4:90:79:49:0a:f1:b3:8a:db:9f:73:2d:75:d6:f9.
  4. Are you sure you want to continue connecting (yes/no)? yes
  5. Warning: Permanently added '192.168.0.1' (RSA) to the list of known hosts.
  6. Password:
  7.  
  8. Last login: Fri Sep 3 05:15:21 2010 from 192.168.0.82
  9. mec@proxy-1:~$

ssh采用交互方式询问用户密码,一旦认证成功,将会为用户返回一个shell。

SSH服务器默认在端口22运行。不过,有些运行SSH服务的服务器并不在这个端口运行。针对这种情况,用ssh命令的 -p port_no指定端口。

要连接运行在端口422之上的SSH服务器,可以使用:

  1. $ ssh user@locahost -p 422

你可以在远程主机的shell中执行命令。shell是一个交互式工具,用户可以在其中输入命令并执行它。然而在shell脚本环境中,我们不需要交互式的shell,而是需要将任务自动化。我们需要在远程shell中执行若干命令,然后在本地主机上显示或存储输出内容。每次都要输入密码对于自动化脚本来说显然不实际,因此要对SSH进行自动登录配置。

7.7节讲解了SSH命令。

在运行使用了SSH的自动化脚本之前,要确保配置了自动登录。

要想在远程主机中运行命令,并将命令输出显示在本地shell,使用下面的语法:

  1. $ ssh user@host 'COMMANDS'

例如:

  1. $ ssh mec@192.168.0.1 'whoami'
  2. Password:
  3. mec

可以输入多条命令,在命令之间以分号进行分隔:

  1. $ ssh user@host 'command1 ; command2 ; command3'

命令可以通过stdin发送,而命令输出可以通过stdout来获取。

语法如下:

  1. $ ssh user@remote_host "COMMANDS" > stdout.txt 2> errors.txt

COMMANDS部分应该用引号括起来,以避免分号被本地主机的shell当做定界符。我们也可以通过stdin将包含管道的命令序列传递给SSH命令:

  1. $ echo "COMMANDS" | sshuser@remote_host> stdout.txt 2> errors.txt

例如:

  1. $ ssh mec@192.168.0.1 "echo user: $(whoami);echo OS: $(uname)"
  2. Password:
  3. user: slynux
  4. OS: Linux

在这个例子中,远程主机上执行的命令是:

  1. echo user: $(whoami);
  2. echo OS: $(uname)

写成一般化的形式就是:

  1. COMMANDS="command1; command2; command3"
  2. $ ssh user@hostname "$COMMANDS"

我们也可以在命令序列中用( )子shell操作符传递一个更复杂的子shell。

现在,编写一个基于SSH的shell脚本,用来收集一组远程主机的运行时间(uptime)。运行时间是系统加电运行的时间。uptime命令用来显示系统加电后运行了多久。

假设IP_LIST中的所有系统都有一个用户test。

  1. #!/bin/bash
  2. #文件名: uptime.sh
  3. #用途:系统运行时间监视器
  4.  
  5. IP_LIST="192.168.0.1 192.168.0.5 192.168.0.9"
  6. USER="test"
  7.  
  8. for IP in $IP_LIST;
  9. do
  10. utime=$(ssh $USER@$IP uptime | awk '{ print $3 }' )
  11. echo $IP uptime: $utime
  12. done

输出应该是:

  1. $ ./uptime.sh
  2. 192.168.0.1 uptime: 1:50,
  3. 192.168.0.5 uptime: 2:15,
  4. 192.168.0.9 uptime: 10:15,

7.8.3 补充内容

让我们看看ssh命令的另一些选项。

  • SSH的压缩功能

SSH协议也支持对数据进行压缩传输,当带宽有限时,这一功能很方便。用ssh命令的选项-C启用压缩功能:

  1. $ ssh -C user@hostname COMMANDS
  • 将数据重定向至远程shell命令的stdin

有时候我们需要将一些数据重定向到远程shell命令的stdin。通过下面的例子看看这如何实现:

  1. $ echo "text" | ssh user@remote_host 'cat >> list'

或者:

  1. # 将文件中的数据重定向
  2. $ ssh user@remote_host 'cat >> list' < file

cat >> list将通过stdin接收到的数据添加到文件list中。这条命令是在远程主机上执行的,但数据却是从本地主机传递到远程shell的stdin的。

7.8.4 参考

7.7节讲解了如何配置自动登录来执行命令而无需提示输入密码。