I have the following series of commands:

cd / && ls | ( cd /tmp && cat >dumpfile)

This series of commands does the following: it creates a file named /tmp/dumpfile. This file contains a listing of the root directory.

The cd / && ls output gets piped to a subshell. What I find odd is that in the subshell, instead of cd /tmp swallowing the ls output, the later cat >dumpfile gets it and writes it to a file. What is going on here?


The pipe sets up stdout to go from ls to the subshell.

In the subshell, cd /tmp and cat are done in the same process.

cd /tmp doesn't read from stdin (the pipe), so when cat reads from stdin, it gets all of ls's output.

  • Is it sufficient for the first command to have no process? What about ls | ( /bin/echo hi; /bin/cat ) which runs echo and cat as separate processes, but cat still reads stdin from ls instead of /bin/echo? – mrb Aug 17 '12 at 13:31
  • If the first command is not a builtin, the shell will have to do an extra fork. But that doesn't matter, because children inherit their parents' file descriptors. – Mikel Aug 17 '12 at 13:35
  • Thanks! To elaborate on your answer even further: I checked the cd's definition in IEEE Std 1003.1-2008. In the "STDIN" and "STDOUT" sections it says both streams are (almost always) not used by cd. – Abdull Aug 17 '12 at 13:42

cd doesn't swallow the output because it doesn't want to. Consider this:

{ ls; date; } | (cd /tmp && date >> date.txt && cat date.txt && cat >dumpfile)

Only the last cat >dumpfile will save the stdin coming from the pipe, because none of the other commands want to consume it.

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.