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

先看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/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种方法:

1
2
3
4
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.

或者

1
2
3
4
5
6
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放到后台中执行. 以下是几种写法的综合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/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"

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