我一直在用这个撞击墙壁一段时间.
我想要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"
此脚本正常工作.如果出现连接问题则返回255,如果机器正忙则返回1,如果一切正常则返回0.如果有人知道更好的方法,请告诉我.
接下来我尝试使用while读取循环在我的机器上调用tssh,这就是出错的地方.一旦tssh返回0,循环就会退出,并且永远不会完成整个集合.
while read nu ; do tssh "MYBOXES$nu" ; done < <(ruby -e '(0..20).each { |i| puts i }')
起初我认为这是一个子壳问题,但显然不是.任何帮助,以及对风格/内容的评论,将不胜感激!我知道当我发现原因时我会踢自己...
克里斯是对的.循环中断的来源是使用stdin的SSH,但是使用循环方法时枪是正确的.
如果要循环输入(例如,带有主机名列表的文件)并调用SSH,则需要传递-n参数,否则基于输入的循环将失败.
while read host; do ssh -n $host "remote command" >> output.txt done << host_list_file.txt
在构造中
something | while read x; do ssh ... done
while循环看到的标准输入是输出something
.
默认行为ssh
是读取标准输入.这可以让你做的事情
cat id_rsa.pub | ssh new_box "cat - >> ~/.ssh/authorized_keys"
现在,说到这一点,当读取第一个值时,第一个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
我今天碰到了这个 - rsh和/或ssh可以打破一段时间读取循环,因为它使用stdin.我把一个-n放入ssh行,阻止它尝试使用stdin并修复了问题.
大多数答案都是针对ssh的.其他命令也劫持stdin并且没有-n选项.这应该解决任何其他命令.这也适用于ssh.
while read x; do # Make sure command does not hijack stdin echo "" | command $x done < /path/to/some/file