Redirection cheat sheet
Every bash redirection operator on one page, from > and 2>&1 to here-strings, exec and process substitution.
Redirections are applied left to right before the command runs, and n>&m copies a descriptor
as it is at that moment. fd 0 is standard input, 1 standard output, 2 standard error. Rows
marked bash-only fail or behave differently under a POSIX sh such as dash. The full
explanation is in the Redirection guide.
Output
echo one > f.txt; echo two > f.txt; cat f.txt>writes stdout to a file, truncating it first.twoecho one >> f.txt; echo two >> f.txt; cat f.txt>>appends to the file instead of truncating.one twols missing.txt 2> err.txt; cat err.txt2>sends standard error to a file.ls: cannot access 'missing.txt': No such file or directoryls todo.txt missing.txt > all.txt 2>&1; cat all.txt- Both streams to one file.
> filemust come before2>&1.ls: cannot access 'missing.txt': No such file or directory todo.txt ls todo.txt missing.txt 2>&1 > out.txt; echo "file has: $(cat out.txt)"- Wrong order: the error still goes to the terminal, only stdout reaches the file.ls: cannot access 'missing.txt': No such file or directory file has: todo.txt
ls todo.txt missing.txt &> all.txt; wc -l < all.txt&>is bash shorthand for> file 2>&1;&>>appends. Bash-only.2ls missing.txt > /dev/null 2>&1; echo "status $?"- Discard all output and keep only the exit status.status 2
echo "warning: low disk" >&2>&2(same as1>&2) writes a message to standard error.
Input
wc -l < todo.txt<connects a file to standard input; the command sees no file name.5tr a-z A-Z <<EOF- Here-document: lines up to
EOFbecome stdin;$varand$(...)are expanded. cat <<'EOF'- Quoted delimiter: the here-document body is passed literally, no expansion.
cat <<-EOF- Strips leading tabs (not spaces) from body lines and the delimiter line.
tr a-z A-Z <<< "hello there"- Here-string: one expanded word plus a newline as stdin. Bash-only.HELLO THERE
read -r a b <<< "web01 10.0.0.11"; echo "$b"- Split a string into variables without a pipe or subshell.10.0.0.11
Descriptors and exec
exec 3> fd3.log; echo "via fd 3" >&3; exec 3>&-; cat fd3.log- Open fd 3 for writing, write to it, close it with
3>&-.via fd 3 exec 4< todo.txt; read -r first <&4; read -r second <&4; echo "$first / $second"- Open a file on fd 4 for reading; each
readcontinues where the last stopped.buy milk / fix login bug exec {log}>> app.out; echo "fd is $log"; echo hi >&$log; cat app.out{name}>lets bash pick a free descriptor (10 or above) and stores it in$name. Bash-only.fd is 10 hiexec > run.log 2>&1- Redirect everything the rest of the script prints.
{ echo header; sort data/fruits.txt | uniq; } > out.txt; head -n 3 out.txt- Redirect a whole group of commands, opening the file once.header apple banana
ls todo.txt nope.txt 3>&1 1>&2 2>&3 3>&- | tr a-z A-Z- Swap stdout and stderr; here only the error goes through the pipe.todo.txt LS: CANNOT ACCESS 'NOPE.TXT': NO SUCH FILE OR DIRECTORY
exec 3<> data.txt<>opens a file for reading and writing on one descriptor.
Pipes and process substitution
ls todo.txt missing.txt 2>&1 | wc -l- Send both streams through a pipe (portable form).2
ls todo.txt missing.txt |& wc -l|&is bash shorthand for2>&1 |.2ls todo.txt missing.txt 2>&1 > /dev/null | sed "s/^/ERR: /"- Pipe only standard error, discard standard output.ERR: ls: cannot access 'missing.txt': No such file or directory
diff <(sort -u data/fruits.txt) <(printf "%s\n" apple banana)<(cmd)is a file name to read cmd's output from. Bash-only.3,6d2 < cherry < date < elderberry < figecho hi | tee >(tr a-z A-Z) > /dev/null | cat>(cmd)is a file name whose contents go to cmd's stdin. Bash-only.HI
Safety
set -o noclobber; echo x > todo.txt; echo "status $?"noclobbermakes>refuse to overwrite an existing file./bin/bash: line 1: todo.txt: cannot overwrite existing file status 1set -o noclobber; echo x >| todo.txt; cat todo.txt>|overwrites even with noclobber set.xsort todo.txt > todo.txt; wc -c < todo.txt- Trap: the shell truncates the output before the command reads it. Use a temp file or
sort -o.0
From https://opscape.vip/cheatsheets/redirection/ · checked 2026-10-31