Dav*_*ave 1 ssh cygwin bash openssh bash-scripting
我将主机名列表存储在名为 ssh_hosts.txt 的文件中。在 shell 脚本中,我循环访问 ssh_hosts.txt 中的主机名,并通过 SSH 在指定主机上执行命令。shell 脚本如下所示。
问题是脚本在处理第一个主机后退出。但是,如果我除了通过 ssh 在指定主机上执行命令之外执行其他操作,脚本将运行完成。
在下面的示例中,我注释掉了对 ssh 的调用,并将其替换为当前主机名的简单回显。这将运行直至完成。
我从 Windows 7 上的以下 Cygwin 版本下运行的 bash shell 执行此脚本:
$ uname -a
CYGWIN_NT-6.1 myHostname 1.7.16(0.262/5/3) 2012-07-20 22:55 i686 Cygwin
Run Code Online (Sandbox Code Playgroud)
涉及到的SSH版本有:
$ ssh -V
OpenSSH_6.0p1, OpenSSL 1.0.1c 10 May 2012
$ ssh myUsername@remoteHost 'ssh -V'
myUsername@remoteHost password:
OpenSSH_6.7p1 Debian-5+deb8u3, OpenSSL 1.0.1t 3 May 2016
Run Code Online (Sandbox Code Playgroud)
这是 shell 脚本:
#!/bin/bash
if [[ $# -ne 1 ]]; then
echo "Usage: $(basename $0) <user name>"
exit 1
fi
USER="$1"
while IFS='' read -r ssh_host || [[ -n "$ssh_host" ]];
do
# This line will execute for all hosts listed in ssh_hosts.txt.
echo $ssh_host
# This line will execute for *only the first* host in ssh_hosts.txt.
# ssh $USER@$ssh_host 'echo $(whoami)@$(hostname)'
done < ssh_hosts.txt
Run Code Online (Sandbox Code Playgroud)
如何让这个 shell 脚本在 ssh_hosts.txt 中的所有主机上执行,而不仅仅是在第一个主机上执行?
您的循环中有两个程序都从 stdin 读取:read 和 ssh。当循环运行时,读取命令将从 ssh_hosts.txt 读取第一行,然后 ssh 读取其余内容。这就是为什么您只看到它连接到第一个主机。
我知道这个问题有两种解决方案。一种是重写循环,使其不会从标准输入重定向。做到这一点的一个好方法是使用forEggo 在他的帖子中的循环。
另一个解决方案是将-n选项传递给ssh:
ssh -n $USER@$ssh_host 'echo $(whoami)@$(hostname)'
Run Code Online (Sandbox Code Playgroud)
这告诉 ssh 不要使用 stdin,将 ssh_hosts.txt 的完整内容留给 read 命令。此解决方案要求您的 ssh 会话不需要与用户进行任何交互,包括提示输入密码(因此使用 ssh 密钥进行身份验证)。
| 归档时间: |
|
| 查看次数: |
9132 次 |
| 最近记录: |