2019年2月13日 星期三

while read搭配pipe要注意變數值的傳遞

當Bash使用while read來讀檔案的時候,若是用到pipe (|)直接傳送結果給while read,要注意後面的while read部分會在另外一個shell裡面執行;故在while read迴圈裡面改變變數的數值並不會導致原始script裡面的變數值,這點要很小心

例1:使用while read讀取/etc/passwd計算行數,沒有使用pipe

n=0
while read LINE
do
    n=$(($n+1)) 
done < /etc/passwd
echo "The value of n is $n"
上述的變數n會顯示/etc/passwd的行數

例2:使用while read搭配pipe的使用來計算/etc/passwd計算行數

n=0
cat /etc/passwd | while read LINE
do
    n=$(($n+1)) 
done
echo "The value of n is $n with pipe."
這邊的變數n,印出來會是0。這是因為經過pipe之後,後面的while read會另外開一個shell執行,故迴圈裡面的n雖然有增加了,但是跟此script裡面的n並不會是同一個。因此最終印出來的n會是一開始宣告的0。
若不想要另外產生一個檔案,解決方案是使用here string (<<<)

例3:使用while read搭配here string

n=0
while read LINE
do
    n=$(($n+1)) 
done <<< "$(cat /etc/passwd)"
echo "The value of n is $n by here string."
這樣變數n就會是/etc/passwd的行數了。
這個方法的好處在於,輸入的部分不用新產生檔案,而且還可以使用pipe


例4:使用while read搭配here string,指令部分即可使用pipe

n=0
while read LINE
do
    n=$(($n+1)) 
done <<< "$(cat /etc/passwd | grep bash)"
echo "The value of n is $n by here string with pipe."
這樣就可以同時使用pipe,然後變數也會被改變。
另外,上面的 n=$(($n+1)) 可以改成 let n++


參考資料

相關資料

_EOF_

A beautiful night in the swedish countryside, watercolor painting by Vladimir Volegov

Steps: 20, Sampler: DPM++ 2M Karras, CFG scale: 7, Seed: 1404810824, Size: 512x256, Model hash: 6ce0161689, Model: v1-5-pruned-emaonly, Version: v1.6.1

Time taken: 1 min. 14.9 sec. on Nvidia MX550
A: 1.70 GB, R: 2.26 GB, Sys: 2.0/2 GB (100.0%)

沒有留言:

張貼留言