或許你應該在其餘腳本中見過下面的這種寫法:
while read line
do
…
done < file
剛開始看到這種結構時,很難理解< file是如何與循環配合在一塊兒工做的。由於循環內有不少條命令,而咱們以前接觸的重定向都是爲一條命令工做的。這裏有一個原則,這個原則掌握好了,這個問題就很簡單了:
對循環重定向的輸入可適用於循環中的全部須要從標準輸入讀取數據的命令;
對循環重定向的輸出可適用於循環中的全部須要向標準輸出寫入數據的命令;
當在循環內部顯式地使用輸入或輸出重定向,內部重定向覆蓋外部重定向。
上面的while結構中,read命令是須要從標準輸入中讀取數據的。咱們來詳細瞭解一下read命令的用法吧,這個命令是shell腳本中使用頻率最高的命令之一。
read
先來看一下read的命令語法:
read arg1 arg2 arg3 arg4 …
read是一個用來賦值的命令,它須要從標準輸入得到值,而後把這些值按位置依次賦值給變量arg一、arg二、arg三、arg4…,輸入的時候以空格做爲字段分隔符。
read的一個最大特性是能夠在腳本中產生交互,由於它從標準輸入讀取數據。read之因此很經常使用,一是由於咱們常常須要賦值,二是由於它能夠交互,三是read可以一次給多個變量賦值。
$ read host ip name
linux 10.0.0.1 licong
$ echo $host $ip $name
linux 10.0.0.1 licong
$
能夠看到,linux、10.0.0.一、licong分別被賦值給了變量host、ip和name。再看:
$ read host ip
linux 10.0.0.1 licong
$ echo $host
linux
$ echo $ip
10.0.0.1 licong
$
當咱們輸入的字段比變量數目多時,最後一個變量的值將不僅一個字段,而是全部剩餘的內容;當輸入字段比變量數少時,多餘的變量將是空值,你能夠本身試試。如今咱們再來看
while read line
do
…
done < file
read經過輸入重定向,把file的第一行全部的內容賦值給變量line,循環體內的命令通常包含對變量line的處理;而後循環處理file的第二行、第三行。。。一直到file的最後一行。還記得while根據其後的命令退出狀態來判斷是否執行循環體嗎?是的,read命令也有退出狀態,當它從文件file中讀到內容時,退出狀態爲0,循環繼續驚醒;當read從文件中讀完最後一行後,下次便沒有內容可讀了,此時read的退出狀態爲非0,因此循環纔會退出。
另外一種也很常見的用法:
command | while read line
do
…
done
若是你還記得管道的用法,這個結構應該不難理解吧。command命令的輸出做爲read循環的輸入,這種結構長用於處理超過一行的輸出,固然awk也很擅長作這種事。
APP_FILE=./aabb(這個是多行文件)
cat $APP_FILE|while read line
do
ssh -q $line ls /home/admin
done
fail: 只執行了一次,就退出了循環
cat $APP_FILE|while read line
do
ssh -q $line ls /home/admin
done
fail: 只執行了一次,就退出了循環
這裏的問題是全部的內容都一塊兒讀取出來寫到緩存裏面了,讓SSH重定向出去了
注意:
1. ssh命令在每次執行時,會讀取全部的標準輸入中的內容。html
cat file |ssh 1.1.1.1 cat 會讀取全部文件的內容linux
2. 對於while循環,當按照以下方式使用時:shell
cat file | while read line緩存
這裏使用重定向,將文件內容輸入到while命令,while命令每次使用read從輸入中讀取一行數據。bash
問題就在這裏,若是在while循環中調用了ssh命令,那麼ssh就會把當前輸入中全部的數據讀走,也就是cat file重定向給while命令的數據,都被ssh命令讀走了,以致於下次循環的時候,read讀到的內容爲空,致使循環提早結束。ssh
解決這個問題兩種方式post
1. ssh -n 使用-n參數spa
2. ssh xxxx < /dev/null重定向shell命令的輸入code
主要參數說明:
-l 指定登入用戶server
-p 設置端口號
-f 後臺運行,並推薦加上 -n 參數
-n 將標準輸入重定向到 /dev/null,防止讀取標準輸入
-N 不執行遠程命令,只作端口轉發
-q 安靜模式,忽略一切對話和錯誤提示
-T 禁用僞終端配置
參考文章
http://blog.163.com/clevertanglei900@126/blog/static/11135225920118742327322/
一 、重定向法;管道法: cat $FILENAME | while read LINE
Function While_read_LINE(){
cat $FILENAME | while read LINE
do
echo $LINE
done
}
註釋:我只全部把這種方式叫作管道法,相比你們應該能夠看出來了吧。當碰見管道的時候管道左邊的命令的輸出會做爲管道右邊命令的輸入而後被輸入出來。
2、實例
一、pri.sh
二、dirr