我不小心输入了
cd /tmp | tail
这当然不是我的意思。但令我惊讶的是,我随后没有更改目录。为什么是这样?用于比较
cd /tmp > /tmp/foo
做导致目录更改,因此它本身不是输出重定向。这里发生了什么?
答案1
管道涉及子 shell,其中部分子 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
输出喷洒遍地/
,或其他此类假设的混乱......