我一直用这个来撞墙一段时间。
我想通过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 }')
起初我认为这是一个子壳问题,但显然不是。 任何帮助,以及对风格/内容的评论,将不胜感激! 我知道当我发现原因时我会踢自己......
答案 0 :(得分:40)
如果要循环输入(例如带有主机名列表的文件)并调用SSH,则需要传递-n参数,否则基于输入的循环将失败。
while read host; do
ssh -n $host "remote command" >> output.txt
done << host_list_file.txt
答案 1 :(得分:33)
在构造
中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
答案 2 :(得分:7)
我今天碰到了这个 - rsh和/或ssh可以打破一段时间读取循环,因为它使用stdin。我把一个-n放到ssh行中,这阻止了它尝试使用stdin并修复了问题。
答案 3 :(得分:6)
大多数答案都是针对ssh的。其他命令也劫持stdin并且没有-n选项。这应该解决任何其他命令。这也适用于ssh。
while read x; do
# Make sure command does not hijack stdin
echo "" | command $x
done < /path/to/some/file
答案 4 :(得分:4)
不知道它是否会有所帮助,但更清晰的写作方式
for nu in `ruby -e '(0..20).each { |i| puts i}'`; do
tssh "MYBOXES$nu"
done
答案 5 :(得分:3)
我也不确定它失败的原因,但我喜欢xargs
和seq
:
seq 0 20 | xargs -n1 tssh MYBOXES
答案 6 :(得分:3)
正如Kaii所说,调用ruby或seq(在BSD或OSX机器上不起作用)只是输出一系列数字真是太过分了。如果您对使用bash感到满意,可以:
for i in {0..20}; do
# command
done
我相信这应该适用于bash 2.05b及以上版本。
答案 7 :(得分:2)
我不能相信这是0的结果打破了你的循环,你可以通过在循环中用“/ bin / true”替换你的tssh命令来测试,这也返回0。
关于样式我不明白为什么一个简单的循环shell脚本需要ruby,perl,seq或jot或者不在我的* BSD上的任何其他二进制文件。
你也可以使用内置for loop构造的shell,它至少在ksh,bash中起作用:
for ((i=0; $i<=20; i++)); do
tssh "MYBOXES$i"
done
答案 8 :(得分:2)
坚持使用while循环并同时保持ssh的另一种方法是使用“-n”开关在ssh / dev / null上创建STDIN。对我来说就像一个魅力:
#!/bin/bash
[...]
something|while read host
do
ssh -nx ${host} fiddleAround
done
(我倾向于总是使用“-x”以避免浪费时间在隧道中协商X.)