Pipe

如果輸出是管道,為什麼cd沒有效果?

  • June 22, 2018

我不小心輸入了

cd /tmp | tail

這當然不是我的意思。但令我驚訝的是,我當時並沒有更改目錄。為什麼是這樣?為了比較

cd /tmp > /tmp/foo

確實會導致目錄更改,因此它不是每個 sé 的輸出重定向。這裡發生了什麼?

管道涉及子 shell,其中的一部分不在父 shell 中執行,因此不會影響該父 shell 程序的工作目錄。這就是 ZSH 的行為方式:

% cd /tmp
% cd /var/tmp | tail
% pwd
/tmp
% echo foo | cd /var/tmp
(pwd now: /var/tmp)
% cd /tmp
% echo foo | cd /var/tmp | echo bar
bar
% pwd
/tmp
% 

請注意目錄僅cd在管道中的最後一個命令時才更改;這是在父 shell 中執行的,因此能夠更改該程序的工作目錄。

此功能的有用用途通常涉及顯式子shell和在其中執行的命令:

dowork | ( cd elsewhere && domorework ) | andyetmore

也一定要對cd呼叫進行錯誤檢查,而不是假設它有效,除非你喜歡rsync輸出到處噴/,或者其他類似的假設混亂……

引用自:https://unix.stackexchange.com/questions/451341