Piping and Redirection

Table of Contents

Redirection(>, >>, 2>, …) reference

$ : > foo.txt  # truncate
$ > foo.txt    # same as above, but some shells don't support

$ echo 'hi' > foo.txt   # stdout
$ echo 'hi' >> foo.txt  # stdout, append

# fd 1 is stdout; same as above
$ echo 'hi' 1> foo.txt
$ echo 'hi' 1>> foo.txt

# fd 2 is stderr (following commands will cause errors)
$ tar 2> foo.txt
$ cp 2>> foo.txt

$ tar &> foo.txt  # both

# redirects stderr to stdout
# (M>&N redirects file descriptor M to file descriptor N, M is 1 if omitted)
$ tar > out.txt 2>&1

# multiple redirections
$ command < input-file > output-file
# '[j]<>filename'
# Open file "filename" for reading and writing, and assign file descriptor "j" to it.
# 'n<&-' Close input file descriptor n.
# '0<&-', '<&-', Close stdin
$ echo 1234567890 > File    # Write string to "File".
$ exec 3<> File             # Open "File" and assign fd 3 to it.
$ read -n 4 <&3             # Read only 4 characters.
$ echo -n . >&3             # Write a decimal point there.
$ exec 3>&-                 # Close fd 3.
$ cat File                  # ==> 1234.67890
#  Random access, by golly.

Pipe stderr, and not stdout? howto

command 2>&1 >/dev/null | grep 'something'

Empty the contents of a file howto

> filename                   # clever
cp /dev/null filename        # naive
cat /dev/null > filename     # intuitive
dd if=/dev/null of=filename  # efficient
truncate filename --size 0   # explicit

Process Substitution(<(commmand), >(command)) reference

<(command)
Runs command and make its output appear as a file.
$ diff <(sort file1) <(sort file2)
>(command)
Captures output that would normally go to a file, and redirect it to the input of a process.
$ cat foo | tee >(tr '[:lower:]' '[:upper:]')
hello, world  #    stdout of tee (original output)
HELLO, WORLD  # file part of tee (process substitution)

Use command output as a file howto

diff /etc/hosts <(ssh somehost cat /etc/hosts)