for與while循環讀行及嵌套ssh的區別

  有個需求:有三列信息文本,第一列IP,第二列用途,第三列備註,需要登錄每個IP執行命令,不符合執行命令結果的,打印出文本中這一行信息。 
   需求很簡單,只要用一個循環,能逐一登錄到每臺機器,執行命令就可以了,剛開始以爲只要5分鐘就能搞定的事情,結果花費了我一個上午的時間。主要耽擱在while循環裏面嵌套了ssh。 
   首先說說for跟while讀行的區別,如都只有一列,結果是一樣的,但是如果多列,比如txt內容這樣: 
line1 line2  line2 
line4  line5  line6 
用for循環: 
for line in `cat txt`; 
do echo $line; 
done 
顯示的結果: 
line1
line2
lien3
line4 
line5 
line6 
用while循環: 
cat txt|while read line; 
do echo $line; 
done 
顯示的結果: 

line1 line2  line2 
line4  line5  line6 
   因此我的需求能用while來做,腳本如下: 
cat txt|while read line
do
IP=`echo $line|awk '{print $1}'`
ssh -o ConnectTimeout=10 ${IP} "ls -l /home/admin|grep /"keyword/""
    if [ ! $? == "0" ];then
        echo "$line"
     fi
done 
   但是問題來了,執行後,只做了一行就結束了,剛開始還懷疑難道是if判斷有問題,一個if結束就退出來了,於是在腳本的每一步都加了調試信息,結果很快發 現並不是if結束就退出來了。於是就逐個註釋掉調試,發現把ssh這句註釋了就能繼續下去,難道ssh哪裏寫錯了?原因不是這樣的。後來在網上查了資料, 發現這麼一句話:while中使用重定向機制。也就是說一開始做while循環,txt全部內容已經被重定向給while循環,而ssh語句正好會讀取輸入中的所有東西。於是自己調試一下: 
    
  cat txt|while read line
do
IP=`echo $line|awk '{print $1}'`
ssh ${IP} "cat"
done 
  顯示結果: 
line4  line5  line6 
也就是是說,最後一行已經讀完了,循環也就結束了。 
解決辦法:將ssh的輸入重定向輸入。 
  
cat txt|while read line
do
IP=`echo $line|awk '{print $1}'`
ssh -o ConnectTimeout=10 ${IP} "ls -l /home/admin|grep /"keyword/"" </dev/null
    if [ ! $? == "0" ];then
        echo "$line"
     fi
done 
ssh最後加上  </dev/null 問題解決。 
轉載自:http://fengshihua.cublog.cn


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章