while循环中碰到ssh的话,如何避免退出

先看一个例子:

#!/bin/sh
. /root/.bash_profile

cat /home/yejr/alldb|while read LINE
do
   #取得IP和组号
   IP=`echo $LINE | awk '{print $1}'`
   NU=`echo $LINE | awk '{print $2}' | awk -F '-' '{print $1}'`

   cnt=`ssh root@$IP "mysql -e 'select count(*) from yejr.tbl1'|tail -n 1"`

   echo "$IP $NU $cnt"
done

看起来没有问题吧,实际上,执行的时候只循环了一次,就退出while循环了,为什么呢?

这是因为ssh需要从输入终端来读取数据,在第一次循环时ssh就把 read 读到的数据也给读取了,相当于是被他"吃"了.
解决办法是,指定 ssh 的输入终端,有3种方法:

ssh -f
-f Requests ssh to go to background just before command execution.  This is useful if ssh is going to ask for
   passwords or passphrases, but the user wants it in the background.  This implies -n.  The recommended way to
   start X11 programs at a remote site is with something like ssh -f host xterm.

或者:

ssh -n
-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 automati-
   cally 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.)

或者,将ssh放到后台中执行. 以下是几种写法的综合:

#!/bin/sh
. /root/.bash_profile

cat /home/yejr/alldb|while read LINE
do
   #取得IP和组号
   IP=`echo $LINE | awk '{print $1}'`
   NU=`echo $LINE | awk '{print $2}' | awk -F '-' '{print $1}'`

   #-f
   #cnt=`ssh -f root@$IP "mysql -e 'select count(*) from yejr.tbl1'|tail -n 1"`

   #-n
   #cnt=`ssh -n root@$IP "mysql -e 'select count(*) from yejr.tbl1'|tail -n 1"`

   #放后台
   #cnt=`ssh root@$IP "mysql -e 'select count(*) from yejr.tbl1'|tail -n 1" &`

   #指定输入设备
   cnt=`ssh root@$IP "mysql -e 'select count(*) from yejr.tbl1'|tail -n 1" /null`

   echo "$IP $NU $cnt"
done

不知道是否还有其他方法呢?

技术相关:

评论

way4:

ssh root@IP < /dev/null

ssh root@IP "cmd" < /dev/null

利用重定向来关闭ssh的标准输入,这样ssh就不会吃东西了。

跟-n参数一个意思,表现不同而已。

你没理解我上面事先设定好的前提,我以前也是这么用的,在循环情况下会退出,只循环一次。

MySQL方案、培训、支持
MySQL 用户组

我是说

ssh IP "cmd " </dev/null
跟 ssh -n是一样的,

真纳闷,这里两次留言半角的</dev/null都没显示出来。

是不是后台把它“吃”了……

呵呵,是的,2者相同效果。
估计是你留言时选择html代码模式导致被吃掉的 :)

MySQL方案、培训、支持
MySQL 用户组