2016-09-19 197 views
1

在Bash中,命令tee運行後,某些全局變量將會意外取消設置。意外的環境變量未設置

測試代碼如下:

#!/bin/bash 
function set_global_variable(){ 
     GLOBAL_VARIABLE="global_variable" 
     echo "set GLOBAL_VARIABLE($GLOBAL_VARIABLE)" 
} 

function get_global_variable(){ 
     echo "get GLOBAL_VARIABLE($GLOBAL_VARIABLE)" 
} 

function normal_test(){ 
     unset GLOBAL_VARIABLE 
     set_global_variable 
     get_global_variable 
} 

function unnormal_test(){ 
     unset GLOBAL_VARIABLE 
     set_global_variable |tee random_file 
     get_global_variable 
} 

echo "normal_test" 
normal_test 

echo "unnormal_test" 
unnormal_test 

結果:

normal_test 
set GLOBAL_VARIABLE(global_variable) 
get GLOBAL_VARIABLE(global_variable) 
unnormal_test 
set GLOBAL_VARIABLE(global_variable) 
get GLOBAL_VARIABLE() 

GLOBAL_VARIABLE的unnormal_test值爲null,爲什麼呢?

+0

在管道中,命令在子shell中執行,這意味着它們對環境所做的任何更改在父shell中都不可見。 – Leon

回答

1

問題是這一行:

set_global_variable |tee random_file 

當這條線跑,bash將創建一個子shell爲管道的每個組件並運行它們在那裏。所以set_global_variable實際上會設置變量,但它會在一個單獨的過程中完成。當您在下一行中運行get_global_variable時,您仍處於未受此影響的原始進程中。

下面是該效果的簡單的例子:

true | a=1 
echo $a 

這將打印什麼出於同樣的原因如上所述。在另一方面:

true | { a=1; echo $a; } 

將打印1,因爲echo $a從相同的子shell跑了作爲a=1。儘管如此,最後一個例子在實踐中並不是很有用。

所以一般的規則是,不要在子shell中設置變量。