當while遇到重定向 sh的陷阱

2021-06-19 00:52:59 字數 978 閱讀 7082

最近寫指令碼遇到乙個變數在while迴圈中重定向後丟掉的問題,經過幾番查詢,發現解決辦法,分享如下。

以下內容來自網路。

以下是我在程式設計時的親身體會:

先看如下的程式:

#!/bin/sh

count=0

while read line

docount=`expr $count + 1`

done < file

echo $count

問題是這個程式能得到什麼樣的結果?彷彿很明顯,能夠統計檔案file的行數,然而你若執行一下便知,無論file的行數是多少,該程式的輸出始終是0!為什麼?

原來如果使用for,while,until,if,case這些命令時用到了重定向,那麼sh會產生乙個子shell來執行它們。可以想象count在迴圈體中能夠正確的計數,一旦while執行完畢,子shell完成,其內部的變數count就消失了。因而得到的結果是迴圈體外開始賦的值0!

可以避免嗎?試試這樣:

cat file|while read line

docount=`expr $count + 1`

done

echo $count

依然如此!怎麼辦?可以先關閉標準輸入,然後以你要讀取得檔案重新開啟它,這樣就不需要對while命令的輸入進行改向,也就不會用子shell的方式來執行它了。如下:

exececho "abcd"|if [ "abcd" = "abcd" ]; then 

var=7

fiecho $var

輸出當然是空。去掉echo "abcd"|就好了。

所以不了解這一點在程式設計時就會非常危險,試想while,for,case,if,until是多麼的常用,與管道或重定向連著用也是很常見的,可是一旦在其內部使用了什麼變數,就是有進無出,有去無回了。

以上的說法僅限於sh程式設計,對於ksh,bash,據我所知都不會有這個問題,它們處理的時候不會當作子shell來做。其它種類的shell可以自己試一試。

當while遇到重定向 sh的陷阱

當使用while讀取檔案時,可能出現while迴圈中讀取正常,而數值確傳不出去,不論是區域性變數和全域性變數。錯誤 如下 file是檔案的名字 cat file while read line do count expr count 1 done echo count解決方法如下 可以先關閉標準輸入...

nginx網域名稱重定向遇到的問題

應客戶要求,需要給客戶配個網域名稱,然後我們的大牛強哥 建議後台不要配備網域名稱伺服器了,這樣不安全,一般都是對外的web伺服器才配置網域名稱 結合另外收藏的乙個博文安裝nginx,然後修改配置檔案如下 乙個網域名稱對應乙個conf檔案 server location share location ...

shell指令碼中while重定向的乙個坑

假設我有乙個需求 從data.txt裡按行讀取乙個檔案,按格式 行號 內容 輸出,再輸出讀取的行數。data.txt youth is not a time.it is a state of mind.oh,you are right.很簡單 bin bash i 0cat data.txt whi...