我一直在用这个撞击墙壁一段时间.
我想要SSH到一组机器并检查它们是否可用(接受连接而不是被使用).我创建了一个小脚本tssh,它就是这样做的:
#!/bin/bash
host=$1
timeout=${2:-1}
ssh -qo "ConnectTimeout $timeout" $host "[ \`who | cut -f1 | wc -l \` -eq 0 ] && exit 0 || exit 1"
Run Code Online (Sandbox Code Playgroud)
此脚本正常工作.如果出现连接问题则返回255,如果机器正忙则返回1,如果一切正常则返回0.如果有人知道更好的方法,请告诉我.
接下来我尝试使用while读取循环在我的机器上调用tssh,这就是出错的地方.一旦tssh返回0,循环就会退出,并且永远不会完成整个集合.
while read nu ; do tssh "MYBOXES$nu" ; done < <(ruby -e '(0..20).each { |i| puts i }')
Run Code Online (Sandbox Code Playgroud)
起初我认为这是一个子壳问题,但显然不是.任何帮助,以及对风格/内容的评论,将不胜感激!我知道当我发现原因时我会踢自己...
小智 41
克里斯是对的.循环中断的来源是使用stdin的SSH,但是使用循环方法时枪是正确的.
如果要循环输入(例如,带有主机名列表的文件)并调用SSH,则需要传递-n参数,否则基于输入的循环将失败.
while read host; do
ssh -n $host "remote command" >> output.txt
done << host_list_file.txt
Run Code Online (Sandbox Code Playgroud)
Foo*_*Bah 34
在构造中
something |
while read x; do
ssh ...
done
Run Code Online (Sandbox Code Playgroud)
while循环看到的标准输入是输出something.
默认行为ssh是读取标准输入.这可以让你做的事情
cat id_rsa.pub | ssh new_box "cat - >> ~/.ssh/authorized_keys"
Run Code Online (Sandbox Code Playgroud)
现在,说到这一点,当读取第一个值时,第一个ssh命令将读取整个输入something.然后,在ssh完成时,没有输出,并read停止.
修复ssh -n ...例如是
cat /etc/hosts | awk '{print $2}' | while read x; do
ssh -n $x "do_something_on_the_machine"
done
Run Code Online (Sandbox Code Playgroud)
大多数答案都是针对ssh的.其他命令也劫持stdin并且没有-n选项.这应该解决任何其他命令.这也适用于ssh.
while read x; do
# Make sure command does not hijack stdin
echo "" | command $x
done < /path/to/some/file
Run Code Online (Sandbox Code Playgroud)
不知道这是否有帮助,但是一种更清晰的写作方式是
for nu in `ruby -e '(0..20).each { |i| puts i}'`; do
tssh "MYBOXES$nu"
done
Run Code Online (Sandbox Code Playgroud)