如果通过管道输出,为什么“cd”没有效果?

如果通过管道输出,为什么“cd”没有效果?

我不小心输入了

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输出喷洒遍地/,或其他此类假设的混乱......

相关内容