Shell redirection syntax soup
I always struggle with the syntax for redirecting multiple streams to another command or a file. LLMs do help, but beyond the most obvious cases, it takes a few prompts to get the syntax right. When I know exactly what I'm after, scanning a quick post is much faster than wrestling with a non-deterministic kraken. So, here's a list of the redirection and piping syntax I use the most, with real examples.
Redirecting stdout and stderr
Redirect stdout to a file
Standard way:
This replaces the content of file with the stdout of command. For example:
Print and redirect to file:
Example:
This prints "Hello, world!" to the terminal and also writes it to hello.txt.
Redirect stderr to a file
Standard way:
Sends all errors (stderr) to file. For example:
Print and redirect stderr to file:
Example:
Redirect both stdout and stderr to a file
Common approach:
Combines stdout and stderr into one stream and saves them to file. For example:
Print and redirect both to file:
Example:
Convenient shorthand:
Example:
Append instead of overwriting
Append stdout to a file:
Example:
Print and append stdout to file:
Example:
Append both stdout and stderr (explicit):
Example:
Print and append both stdout and stderr to file:
Example:
Convenient shorthand for appending both:
Example:
Piping output
Pipe stdout to another command
Basic usage:
This sends the stdout of command1 to the input of command2. For example:
Print and redirect piped stdout to file:
Example:
Pipe both stdout and stderr
Common way:
Combines stdout and stderr, then pipes the combined stream to command2. For example:
Print and redirect both stdout and stderr to file:
Example:
Shorthand for piping both stdout and stderr (|&)
Shorthand syntax:
This is equivalent to command1 2>&1 | command2, combining stdout and stderr. For example:
Print and redirect both stdout and stderr using |&:
Example:
Redirecting file descriptors
Custom file descriptors
Create a new file descriptor (e.g., 3) and redirect stdout to it:
This sends the stdout of command to file descriptor 3, which points to outputfile. For example:
Print and redirect stdout to custom file descriptor:
This prints "Using FD 3" to the terminal and simultaneously writes it to custom_output.txt.
Redirect stderr to a file descriptor
Common case:
Redirects stderr to file descriptor 3. For example:
Print and redirect stderr to custom file descriptor:
Example:
Redirect both stdout and stderr to a file descriptor
Common way:
Combines stdout and stderr, and redirects them to file descriptor 3.
Note: There's no shorthand equivalent for redirecting both stdout and stderr to a file descriptor. You need to use the full syntax. For example:
Discarding output
Send stdout and stderr to /dev/null
Common:
Silences all output (stdout and stderr). For example:
Print and discard stdout and stderr (not sure why you'd ever need this):
Example:
Convenient shorthand:
Example:
At a glance
Redirect stdout: command > file
Redirect stderr: command 2> file
Redirect both stdout and stderr:
- Standard: command > file 2>&1
- Shorthand: command &> file
Append stdout: command >> file
Append both stdout and stderr:
- Standard: command >> file 2>&1
- Shorthand: command &>> file
Pipe stdout: command1 | command2
Pipe both stdout and stderr:
- Standard: command1 2>&1 | command2
- Shorthand: command1 |& command2
Custom file descriptors:
- Create and redirect stdout: exec 3> file; command >&3
- Redirect stderr: command 2>&3
- Redirect both stdout and stderr: command > /dev/fd/3 2>&1 (no shorthand available)
Discard stdout and stderr:
- Standard: command > /dev/null 2>&1
- Shorthand: command &>/dev/null
Discussion in the ATmosphere