在while和for中使用ssh差异-SSH重定向机制

在while和for中使用ssh差异-SSH重定向机制
20140609 Chenxin
while :以行读取文件,默认分隔符是空格或者Tab;循环体内有ssh,scp的时候,需要加上</dev/null(不加的话,执行一次循环就退出).若是ssh的话,可以在ssh命令后加个"-n".
for: 以空格读取文件,也就是碰到空格,就开始执行循环体,所以需要以行读取的话,就要把空格转换成其他字符.

遇到问题
在执行以下脚本时,读取了第一行记录后,while就自动跳出循环了(for循环没这个问题).如果没有ssh指令,则正常执行循环,什么原因呢?解决方式可以如下2种.

1.ssh使用-n选项,解决重定向问题;
cat ip.txt|while read line;do
ip=echo $line|awk '{ print $1}'
project_list=echo $line|awk '{print $2,$3,$NF}'
if [ -n "$ip" ];then
echo "++++ $ip $project_list ++++"
grep -q "$ip" /home/web/.ssh/known_hosts || renzheng
ssh -p 4399 -i /home/web/.ssh/id_dsa -n web@"$ip" sudo /root/admin/system_common_check.sh
fi
done

cat ip.txt
117.79.150.186 龙之力量(app)
117.79.150.187 lzll_app_69 龙之 龙之(app)
117.79.150.189 龙之力量(app)

2.使用ssh重定向 ssh $ip ls < /dev/null
最近在写一个自动更新的shell,可是发现如果在使用while循环从一个文件中读取ip地址,然后访问就只能读取第一行纪录。代码如下:
while read LINE
do
echo ******$LINE
ssh 192.168.10.233 ls
done < data
但是如果使用for就没有这个问题,非常的奇怪,for的代码如下:
for LINE in cat data
do
echo ****$LINE
ssh 192.168.10.233 ls
done

原来并不是while的for的差别,而是while中使用了重定向机制,data文件中的信息都已经读入并重定向给了整个while语句。所以当我们在while循环中再一次调用read语句,就会读取到下一条记录。问题就出在这里,ssh语句正好会读取输入中的所有东西,下面这个shell能很好的说明这个问题:
while read LINE
do
echo *************$LINE
ssh 192.168.10.233 cat
done < data
执行这个shell就会发现,ssh中的cat语句会打印出data文件中的其他纪录,这就导致调用完ssh语句后,输入缓存中已经都被读完了,当read语句再读的时候当然也就读不到纪录,循环也就退出了。
改进方法是,将ssh的输入重定向输入:
while read LINE
do
echo *******************************************$LINE
ssh 192.168.10.233 ls < /dev/null
done < data
这样,在while语句中也能顺利的执行ssh语句了。

posted @ 2020-04-20 15:36  ChanixChen  阅读(331)  评论(0编辑  收藏  举报