Bash
bash:變數在讀取循環結束時失去值
我的一個 shell 腳本有問題。問了幾個同事,但他們都只是搖頭(經過一些抓撓),所以我來這裡尋求答案。
根據我的理解,下面的 shell 腳本應該列印“Count is 5”作為最後一行。除非它沒有。它列印“計數為 0”。如果將“while read”替換為任何其他類型的循環,它就可以正常工作。這是腳本:
echo "1">輸入數據 迴聲“2”>>輸入數據 迴聲“3”>>輸入數據 迴聲“4”>>輸入數據 迴聲“5”>>輸入數據 碳納米管=0 貓輸入.數據 | 閱讀時; 做 讓CNT++; echo "計數到 $CNT" 完畢 echo "計數是 $CNT"
為什麼會發生這種情況,我該如何預防?我已經在 Debian Lenny 和 Squeeze 中嘗試過,結果相同(即 bash 3.2.39 和 bash 4.1.5。我完全承認不是一個 shell 腳本嚮導,所以任何指針都將不勝感激。
請參閱參數@Bash FAQ 條目 #24:“我在循環中設置變數。為什麼它們在循環終止後突然消失?或者,為什麼我不能通過管道讀取數據?” (最近存檔在這裡)。
摘要:這僅受 bash 4.2 及更高版本的支持。如果您使用 bash,則需要使用不同的方式,例如命令替換而不是管道。
這是一種“常見”的錯誤。管道創建子外殼,因此
while read
它執行在與您的腳本不同的外殼上,這使得您的CNT
變數永遠不會改變(只有管道子外殼內的那個)。將最後一個
echo
與 subshell組合while
以修復它(還有許多其他方法可以修復它,這是一種。Iain 和 Ignacio 的答案還有其他方法。)CNT=0 cat input.data | ( while read do let CNT++; echo "Counting to $CNT" done echo "Count is $CNT" )
長解釋:
- 您
CNT
在腳本上聲明值為 0;- 一個 SubShell 在
|
to上啟動while read
;- 您的
$CNT
變數被導出到值為 0 的 SubShell;- SubShell 計數並將
CNT
值增加到 5;- SubShell 結束,變數和值被銷毀(它們不會返回到呼叫程序/腳本)。
- 你
echo
原來CNT
的值是0。