在comment on another post,@JonathanLeffler指出:Bash子殼/管道 - 哪些部件在子殼中執行?
{...} |有些命令是在子shell中運行的,並不會影響父shell的 。演示:
X=PQR; echo $X; { X=ABC; echo $X; } | cat; echo $X
(帶輸出PQR,ABC,PQR三線)
確實:
[email protected]:tmp$X=PQR; echo $X; { X=ABC; echo $X; } | cat; echo $X
PQR
ABC
PQR
然而,man bash
說{ .. }
做不在子shell中執行:
{ list; }
list is simply executed in the current shell environment. list must be
terminated with a newline or semicolon. This is known as a group command.
那麼是什麼回事?是man bash
錯?我知道管道的每個部分都在子shell中執行;但我不明白這是怎麼導致觀察到的行爲。例如:
[email protected]:tmp$X=PQR; echo $X | sed; X=ABC; echo $X | sed; echo $X
PQR
ABC
ABC
編輯補充:
有幾個人使用echo $$
表明事情(或者不是)一個子shell的部分建議。這並沒有什麼用處,因爲$$
在參數展開階段得到擴展,在執行任何命令之前就已經發生了。
作爲一個例子:
[email protected]:tmp$echo 1$$; ps; (echo 2$$; ps); echo 3$$; ps
11194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
21194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
7894 ttys000 0:00.00 -bash
31194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
[email protected]:tmp$
可以看到的ps
第二次調用發生子外殼的內部,具有pid 7894
;但echo 2$$
仍然顯示的bash取代在可變膨脹階段,它產生了子外殼
對於對比度之前的值,並表明{ .. }
確實不產卵子shell:
[email protected]:tmp$echo 1$$; ps; { echo 2$$; ps; }; echo 3$$; ps
11194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
21194
PID TTY TIME CMD
1194 ttys000 0:00.22 -bash
31194
PID TTY TIME CMD
1194 ttys000 0:00.23 -bash
只是爲了證明@nos是正確的,管道添加到上面:
[email protected]:tmp$echo 1$$; ps; { echo 2$$; ps; } | sed ; echo 3$$; ps
11194
PID TTY TIME CMD
1194 ttys000 0:00.25 -bash
21194
PID TTY TIME CMD
1194 ttys000 0:00.25 -bash
7945 ttys000 0:00.00 -bash
7946 ttys000 0:00.00 sed
31194
PID TTY TIME CMD
1194 ttys000 0:00.25 -bash
正如預期的那樣,殼產卵2子shell,一個用於管道的每一側上。
我認爲我們有一個贏家。這不是創建子shell的'{..}',它是管道。我實際上剛剛出來並在開始的時候說過。 – 2012-02-02 09:22:04
在'{'之後,至少在我的'bash'版本中需要一個空格。 – krlmlr 2012-02-02 13:02:28
$(cmd args)構造也創建一個子shell:'echo $(echo $ BASH_SUBSHELL)' – 2014-02-07 15:46:04