如果要查看一下某台主机的磁盘使用情况,是不是必须要登录到目标主机上才能执行 df 命令呢?当然不是的,使用 ssh 命令在远程的主机上执行 df 命令,然后直接把结果显示出来。整个过程就像是在本地执行了一条命令一样:
$ ssh nick@xxx.xxx.xxx.xxx "df -h"
那么如何一次执行多条命令呢?其实也很简单,使用分号把不同的命令隔起来就 OK 了:
$ ssh nick@xxx.xxx.xxx.xxx "pwd; cat hello.txt"
第一条命令返回的结果: /home/nick
这说明用这种方式执行命令时的当前目录就是登陆用户的home目录。
第二条命令返回 hello.txt 文件的内容。
有时候我们需要远程执行一些有交互操作的命令。
$ ssh nick@xxx.xxx.xxx.xxx "sudo ls /root"
$ ssh nick@xxx.xxx.xxx.xxx "top"
这两条命令虽然提示的失败原因不同,但它们有一个共同点:都需要与用户交互(需要 TTY)。所以它们失败的原因也是相同的:
默认情况下,当执行不带命令的 ssh 连接时,会分配一个 TTY。因为此时你应该是想要运行一个 shell 会话。
但是当你通过 ssh 在远程主机上执行命令时,并不会为这个远程会话分配 TTY。此时 ssh 会立即退出远程主机,所以需要交互的命令也随之结束。
好在我们可以通过 -t 参数显式的告诉 ssh,我们需要一个 TTY 远程 shell 进行交互!
添加 -t 参数后,ssh 会保持登录状态,直到你退出需要交互的命令。
作为总结,我们看看 -t 参数的官方解释: “Force pseudo-terminal allocation. This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services. Multiple -t options force tty allocation, even if ssh has no local tty.”
在本地创建一个脚本文件 test.sh,内容为:
ls
pwd
然后运行下面的命令:
$ ssh nick@xxx.xxx.xxx.xxx < test.sh
通过重定向 stdin,本地的脚本 test.sh 在远程服务器上被执行。
除了执行本地的脚本,还有一种情况是脚本文件存放在远程服务器上,而需要远程的执行它。
此时在远程服务器上用户 nick 的home目录中有一个脚本 test.sh。文件的内容如下:
ls
pwd
执行下面的命令:
$ ssh nick@xxx.xxx.xxx.xxx "/home/nick/test.sh"
注意,此时需要指定脚本的绝对路径。