Shell – redirection and pipeline

io-redirectionpipeshell

I was wondering about differences and relation between redirection and pipeline.

  1. Is pipeline only used to connect
    stdout output of a command to stdin
    input of another command?
  2. Is redirection only used to connect
    a stdout output of a command to a
    file, and to connect a file to a
    stdin input of a command? But there
    seems to be command >& 2.
  3. A pipeline com1 | com2 can be
    replaced by redirection as com1 >
    tempfile; com2 < tempfile
    . Can the
    replacement be modified to be
    without using a file?
  4. Can a redirection be replaced by a
    pipeline?

Thanks and regards!

Best Answer

  1. Yes. More precisely, in the shell, a pipe connects the standard output of the command on the left to the standard input of the command on the right. Even more precisely, what foo | bar means to the shell is:

    1. Create a pipe.
    2. Fork a child process, and connect the write end of the pipe to its standard output. Then execute foo in this child process.
    3. Fork a child process, and connect the read end of the pipe to its standard input. Then execute bar in this child process.
    4. Wait for both child processes to exit.
  2. Yes. Ordinary redirections indicate a file by name: >foo. Another form of redirection indicates a file by descriptor. For example, >&2 means “redirect standard output to whatever file descriptor 2 is currently connected to”.

    On that topic, note that redirections are processed from left to right. For example, to redirect both standard output and standard error to the same file, use foo >filename 2>&1. The command foo 2>&1 >filename typed in a terminal would first connect standard error to the terminal (which both standard output and standard error are still connected to at that point, so it wouldn't make any difference), then connect standard output to the file.

  3. Yes, but. The pipe construct in the shell creates an anonymous pipe; there are also named pipes.

    mkfifo f
    cat f
    # (in another terminal)
    echo hello >f
    

    Named pipes are a lot rarer than pipelines. They're used when it's necessary to connect two processes that are started independently; this doesn't happen very often, but it's nice to have it when necessary.

    Note that the replacement you gave: foo >tempfile; bar <tempfile is different: first foo writes all of its output to the temporary file, then bar starts running. With a pipeline, the commands run in parallel.

  4. Yes, but it's not very useful.

    cat input_file | some_command   # a uselessly complicated way of writing some_command <input_file
    echo hello | tee output_file    # a uselessly complicated way of writing echo hello >output_file