循環中的重定向
或許你應該在其他腳本中見過下面的這種寫法:
while read line
do
???????…
done < file
剛開始看到這種結構時,很難理解< file是如何與循環配合在一起工作的。因為循環內有很多條命令,而我們之前接觸的重定向都是為一條命令工作的。這里有一個原則,這個原則掌握好了,這個問題就很簡單了:
對循環重定向的輸入可適用于循環中的所有需要從標準輸入讀取數據的命令;
對循環重定向的輸出可適用于循環中的所有需要向標準輸出寫入數據的命令;
當在循環內部顯式地使用輸入或輸出重定向,內部重定向覆蓋外部重定向。
上面的while結構中,read命令是需要從標準輸入中讀取數據的。我們來詳細了解一下read命令的用法吧,這個命令是shell腳本中使用頻率最高的命令之一。
read
先來看一下read的命令語法:
read arg1 arg2 arg3 arg4 …
read是一個用來賦值的命令,它需要從標準輸入獲得值,然后把這些值按位置依次賦值給變量arg1、arg2、arg3、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.1、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也很擅長做這種事。