bash 和 zsh 中 && 與 & 的優先級

bash 和 zsh 中 && 與 & 的優先級

正在接聽這個問題bash我發現和中的行為之間有一個非常有趣(且微妙)的差異zsh

bash

romano@RRyS:~$ pwd
/home/romano
romano@RRyS:~$ alias x="cd /bin && ./echo A >/dev/null  &"
romano@RRyS:~$ x
[1] 16611
romano@RRyS:~$ pwd
/home/romano

正如您所看到的,alias 的執行x是在子 shell 中執行的,因此目前目錄不會改變。

不在zsh

[romano:~] % pwd
/home/romano
[romano:~] % alias x="cd /bin && ./echo A >/dev/null &"
[romano:~] % x
[1] 16744
[1]  + 16744 done       ./echo A >/dev/null                                    
1& [romano:/bin] % pwd
/bin
[romano:/bin] % 

此處目錄已變更。

看來&in 的bash優先權與 in 不同zsh--- 我的意思是,該指令似乎被讀作

(cd /tmp && echo A) & 

bash和作為

cd /tmp && (echo A &) 

zsh。這是正確的還是造成不同行為的原因是另一個?

答案1

不同的、有記錄的行為zshmisc

;列表是零個或多個子列表的序列,其中每個子列表以、&&|&!或換行符終止。當清單作為複雜命令出現在(...)或中時,可以選擇從清單中的最後一個子清單中省略該終止符{...}。當子清單由 或 換行符號終止時;,shell 會等待它完成,然後再執行下一個子清單。如果子清單由&&|或終止&!,則 shell 會在背景執行其中的最後一個管道,並且不會等待它完成(請注意與在背景執行整個子清單的其他 shell 的區別)。後台管道返回零狀態。

答案2

埋藏的zshmisc(1)是以下行:

如果子清單以 &|' 或 `&!' 終止&',,則 shell 在背景執行其中的最後一個管道,

雖然它沒有具體說明子清單中的其他管道在當前 shell 中執行,但這似乎確實是它所暗示的,並且您觀察到的行為支持該解釋。例如:

$ echo $foo $bar

$ foo=3 && bar=5 && sleep 1 &
$ echo $foo $bar
3 5

也支援這樣的概念:前兩個管道在當前 shell 中執行,並且只有子清單的最後一個管道實際上在後台執行。

相關內容