I accidentally typed

cd /tmp | tail

which is of course not what I meant. But to my surprise, I then did not change directory. Why is this? For comparison

cd /tmp > /tmp/foo

does result in a change of directory, so it's not the output redirection per sé. What's going on here?

  • The pipe spawns a subshell that exits when tail exits. I would have expected only tail to be in the subshell, but I guess the cd is as well. – jordanm Jun 22 '18 at 16:21
  • 1
    But cd /tmp | pwd exhibits the same behavior -- pwd shows an unchanged working directory. – DopeGhoti Jun 22 '18 at 16:23
  • Each part of the pipeline is a separate process (maybe except last command). – ctrl-alt-delor Jun 22 '18 at 16:56

Pipes involve subshells, portions of which are not run in the parent shell and thus cannot affect the working directory of that parent shell process. This is how ZSH behaves:

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

Note how the directory only changed when the cd was the last command in the pipeline; this was run in the parent shell proper and thus was able to change the working directory of that process.

A useful use of this feature usually involves an explicit subshell and commands run therein:

dowork | ( cd elsewhere && domorework ) | andyetmore

also be sure to error check the cd call instead of assuming it worked, unless you like rsync output sprayed all over /, or other such hypothetical messes...

  • I understand why tail would need to be in a subshell, but I don't understand by the cd must be in a subshell, for the pipe to work. – gerrit Jun 22 '18 at 23:17
  • having the parent process also run at various random points throughout the pipeline and handling I/O and deadlocks correctly would be much more complicated than simply forking off N children with the I/O wired up correctly – thrig Jun 23 '18 at 14:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.