Bash

bash:變數在讀取循環結束時失去值

  • October 17, 2020

我的一個 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與 subshel​​l組合while以修復它(還有許多其他方法可以修復它,這是一種。Iain 和 Ignacio 的答案還有其他方法。)

CNT=0

cat input.data | ( while read 
do
 let CNT++;
 echo "Counting to $CNT"
done 
echo "Count is $CNT" )

長解釋:

  1. CNT在腳本上聲明值為 0;
  2. 一個 SubShell 在|to上啟動while read
  3. 您的$CNT變數被導出到值為 0 的 SubShell;
  4. SubShell 計數並將CNT值增加到 5;
  5. SubShell 結束,變數和值被銷毀(它們不會返回到呼叫程序/腳本)。
  6. echo原來CNT的值是0。

引用自:https://serverfault.com/questions/259339