2017-09-04 226 views
1

在我當前的項目中,我運行一個循環,在執行過程中定義了一個稍後需要的變量。 一切都運行良好,直到我想添加與三通記錄,以便我以後可以檢查日誌還在一個文件中。 由於我想記錄stdout和stderr,我申請了|&2>&1 |的快捷方式)。 但奇怪的是,變量的值會丟失。Bash:可以記錄影響變量範圍嗎?

for i in 1 2 3 ; do 
    # ... do something meaningful ... 
    myVar=test1 
done |& tee test1 
echo "myVar=$myVar" 

輸出:

myVar= 

同時我發現了一個方法,那效果更好:當我切換到文件重定向進程替換,變量定義作品的組合。

for i in 1 2 3 ; do 
    # ... do something meaningful ... 
    myVar=test2 
done > >(tee test2 ) \ 
    2> >(tee test2 >&2) 
echo "myVar=$myVar" 

輸出:

myVar=foo 

但我想明白了,爲什麼:-)

  1. 爲什麼價值迷失在第一個例子嗎?
  2. 爲什麼不在第二個迷失?

你能告訴嗎?

+1

使用管道在管道的任一側創建一個子殼體,當它結束時,兩端都會關閉而失去內部環境。它無關三通,與任何命令試試。第二種方法僅適用於'>()'所以什麼也沒在那裏不丟失創建一個子shell。 – 123

回答

1

As 123 said管道創建一個子殼(新範圍)和副殼具有與母體殼的變量沒有訪問。

以下的輔助函數示出了外殼的PID和可變a的值。

show_a() { echo $BASHPID: a=$a >&2; } 

以下示例不創建子shell,因爲只使用重定向。只使用一個變量a

$ a=1; show_a; { a=2; show_a; } > /dev/null ; show_a 
31072: a=1 
31072: a=2 
31072: a=2 

但是這個例子創建了一個子shell,因爲管道。並且每個過程都有自己的變量a

$ a=1; show_a; { a=2; show_a; } | tee ; show_a 
31072: a=1 
6375: a=2 
31072: a=1 
+0

明白了!謝謝你們倆。尼斯把戲執行過程中打印$ BASHPID。 – Hardy