While循環從grep讀取多行
我正在 AIX 5.3 中編寫一個腳本,它將遍歷 a 的輸出
df
並根據另一個配置文件檢查每個卷。如果卷出現在配置文件中,它將設置腳本稍後需要的標誌。如果我的配置文件只有一列並且我使用for
循環,那麼這非常有效。然而,我的問題是,如果我使用while read
循環在每行填充多個變數,那麼我在 thewhile
和 the之間設置的任何變數done
都將被丟棄。例如,假設 /netapp/conf/ExcludeFile.conf 的內容是一堆包含兩個欄位的行:
volName="myVolume" utilization=70 thresholdFlag=0 grep volName /netapp/conf/ExcludeFile.conf | while read vol threshold; do if [ $utilization -ge $threshold ] ; then thresholdFlag=1 fi done echo "$thresholdFlag"
在此範例中,thresholdFlag 將始終為 0,即使該卷出現在文件中並且其使用率大於門檻值。我可以
echo "setting thresholdFlag to 1"
在那裡添加一個,看到迴聲,它仍然會在最後回顯一個 0。有沒有一種干淨的方法可以做到這一點?我認為我的 while 循環是在一個子 shell 中完成的,並且我對其中的變數所做的更改實際上是對在
done
.
Zoredache 在聊天中向我指出了這一點,poige 在他的回答中提到了這一點:這個問題可以通過 subshell 解決。
當我不得不從一次
for
從我的 grep 讀取單個變數的循環更改為while read var1 var2
允許我讀取多個變數的循環時,我能夠通過使用括號來保留我在 while 循環中操作的臨時變數定義一個顯式的子shell。這是一個例子:sum=0 grep volume configfile | head -n1 | (while read var1 var2; do let sum=var1+var2 done echo "The sum is $sum.")
沒有括號,您將始終回顯總和 0。使用它們,您將回顯 grep 的第一個匹配行中的前兩個值的總和。
此外,正如 Poige 在另一個答案中指出的那樣,您可以使用子外殼來填充範圍內的變數,如下所示:
var=$( cat file | while read a b; do sum=a+b echo "$sum" done) echo "$var"
在這種情況下,您在最後回顯的 var 的值將是您在循環中計算的最後一個總和,即使 sum 在子外殼的末尾被破壞。