shell指令碼中使用了管道符,導致變數賦值丟失的原因

來源:互聯網
上載者:User
發現這個問題來自對SGE的startmpi.sh指令碼做改造的時候。考慮如下一段shell代碼: 
#!/bin/sh
# declare -i i

testline="hello:"

cat testfile | while read line; do
   testline="${testline}${line} "
   echo "In cycle, the testline is: $testline"

# for (( i=0; i<3; i++ )) do
#    testline="${testline}${i} "

#i=0
#while [ $i -lt 3 ]; do
#   testline="${testline}${i} "
#   i=$i+1

done
echo $testline

 

 代碼中用到的testfile可以是任何文本的檔案,比如: 


phy2 2 
phy3 2 
phy4 2 

這樣的情況下,代碼啟動並執行結果出乎我的意料,testline這個變數在while迴圈中就好像沒有被賦過值一樣,輸出是這樣的: 

In cycle, the testline is: hello:phy2 2 
In cycle, the testline is: hello:phy2 2 phy3 2 
In cycle, the testline is: hello:phy2 2 phy3 2 phy4 2 
hello: 

這是為什麼呢?參考上面的代碼,如果把cat testfile | while read line; do這一段注釋掉,開啟for迴圈那一段,或開啟while迴圈那一段的話,testline就都能在迴圈中被賦值,最後的echo $testline就是正確的。這是為什麼呢? 

最後發現是管道符|引發的問題。原因非常簡單,之前在學習shell的時候就學過shell執行命令的原理,裡面也有對管道的描述。簡單來說,在shell中使用管道符號,會產生subshell,從而使在這個subshell中對變數的賦值只在subshell中生效,不會影響到shell指令碼本身的進程。 

但是ksh現在有個feature,能使管道中對變數的賦值反映到父shell中來,這就是網上有人問說這樣的代碼在k shell中就是OK的原因。 

附上網上搜來的一篇文章,講解的不錯。

 /Files/super119/bash_pipe_variable_lost.mht.zip

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.