When I create a pipe using the shell, for example:

ls | cat

What I know for sure is that the stdin for cat will be the stdout for ls (i.e. everything ls writes to its stdout, cat will read it through its stdin).

Now I have two questions:

  1. Will the stdin for ls be the stdout for cat?
  2. Is the stderr for both ls and cat affected by the pipe operator, or will it still be the inherited stderr value of the shell?
  • 1
    1. No. 2. no, pipe does not do anything to stderr. – NickD Nov 2 '17 at 17:26

Technically, in ls | cat

  • the stdout of ls (its fd 1) will be the writing end of a pipe (or socketpair with ksh93 on some systems).
  • the stdin of cat (its fd 0) will be the reading end of that same pipe
  • both commands will run concurrently (are started at the same time in separate processes)
  • stdin of ls is not affected (question 1)
  • stdout of cat is not affected (question 1)
  • stderr (fd 2) of ls or cat are not affected (question 2).

To have ls's stderr also go to the writing end of the pipe (so cat can read it from its stdin at the other end of the pipe), you can do:

ls 2>&1 | cat

Which says: "make fd 2 point to the same resource as that on fd 1 (here the pipe)"

With csh, tcsh, zsh or bash 4.0 or above, you can also write it:

ls |& cat

On systems where pipes are bi-directional, you could do:

ls <&1 | cat >&0

to have cat's stdout be fed back to ls via that same pipe but in the reverse direction, but that would be pointless as ls never reads from its stdin.

On Linux, where pipes are not bidirectional, that command would give an error.

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.