ssh导致while read line出错

     -n      Redirects stdin from /dev/null (actually, prevents reading from stdin).  This must be used when ssh is run in the
             background.  A common trick is to use this to run X11 programs on a remote machine.  For example, ssh -n
             shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically
             forwarded over an encrypted channel.  The ssh program will be put in the background.  (This does not work if ssh
             needs to ask for a password or passphrase; see also the -f option.)
  • http://blog.csdn.net/zrs19800702/article/details/54407986
  • http://www.cnblogs.com/fjping0606/p/5725953.html
  • 【背景】
    工作过程中遇到要从一个ip列表中获取ip port,然后ssh ip 到目标机器进行特定的操作,但是编写脚本的过程 使用while read line 读取ip列表,在while循环中只读取第一个ip 后就退出脚本的情况。
  • 【介绍】
    解释上面遇到的问题之前,先看到for 与while的测试对比,文中ip经过修改。
    点击(此处)折叠或打开
#/bin/bash
IPS="10.1.1.10 3001
10.1.1.10 3003
10.1.1.11 3001
10.1.1.11 3002
10.1.1.11 3004
10.1.1.11 3005
10.1.1.13 3002
10.1.1.13 3003
10.1.1.13 3004
10.1.1.14 3002"
echo "====while test ===="
i=0

echo $IPS | while read line
do
    echo $(($i+1))
    echo $line
done


echo "====for test ===="
n=0
for ip in $IPS ;
do
   n=$(($n+1))
   echo $ip
   echo $n
done

输出结果如下:

====while test ====
1
10.1.1.10 3001 10.1.1.10 3003 10.1.1.11 3001 10.1.1.11 3002 10.1.1.11 3004 10.1.1.11 3005 10.1.1.13 3002 10.1.1.13 3003 10.1.1.13 3004 10.1.1.14 3002
====for test ====
10.1.1.10
1
3001
2
10.1.1.10
3
3003
4
10.1.1.11
5
3001
6
10.1.1.11
.... 
  • 由例子可见,while read line 是一次性将信息读入并赋值给line ,而for是每次读取一个以空格为分割符的字符串。

  • 【原因】
    while中使用重定向机制,IPS中的所有信息都被读入并重定向给了整个while 语句中的line 变量。所以当我们在while循环中再一次调用read语句,就会读取到下一条记录。问题就出在这里,$line中的最后一行已经读完,无法获取下一行记录,从而退出 while循环。

  • 【解决方法】
    1 使用ssh -n "command"
    2 ssh "cmd" < /dev/null 将ssh 的输入重定向输入。

你可能感兴趣的:(ssh导致while read line出错)