stdin, stdout, stderr and File Descriptors
In this page:
The Three Standard Streams
Every process starts with three open file descriptors: 0 (stdin, input), 1 (stdout, normal output), and 2 (stderr, error output). Bash lets you target any of them explicitly using the N> syntax.
Example: The Three Standard Streams
#!/bin/bash
echo "this goes to stdout" 1>&1
echo "this goes to stderr" 1>&2
Login to try C/C++/Java/PHP code in the editor
Sending Error Messages to stderr
Well-behaved scripts print diagnostics and errors to stderr with >&2 so that normal output on stdout stays clean and can be piped or captured separately.
Note: Use a small log_error helper like this instead of scattering >&2 everywhere.
Example: Sending Error Messages to stderr
#!/bin/bash
log_error() {
echo "ERROR: $1" >&2
}
log_error "something went wrong"
echo "normal output continues on stdout"
Login to try C/C++/Java/PHP code in the editor
Order Matters When Merging Streams
cmd > file 2>&1 first points stdout at file, then makes stderr a copy of the (now redirected) stdout, so both land in file. Reversing the order to cmd 2>&1 > file makes stderr a copy of the *old* stdout (the terminal) before stdout moves to the file.
Warning: Read redirections left to right; 2>&1 > file is a very common bug because it does not do what people expect.
Example: Order Matters When Merging Streams
#!/bin/bash
{ echo "out line"; echo "err line" >&2; } > both.log 2>&1
echo "--- both.log contents ---"
cat both.log
rm -f both.log
Login to try C/C++/Java/PHP code in the editor
Checking Which Stream a Descriptor Points To
The test -t operator (or [ -t N ]) tells you whether file descriptor N is connected to a terminal. In a non-interactive script it usually is not, which is useful for deciding whether to print colored output.
Example: Checking Which Stream a Descriptor Points To
#!/bin/bash
if [ -t 1 ]; then
echo "stdout is a terminal"
else
echo "stdout is redirected or non-interactive"
fi
Login to try C/C++/Java/PHP code in the editor
- Thinking error messages printed with
echoautomatically go to stderr; plainechoalways writes to stdout (fd 1) unless redirected. - Confusing the order of
2>&1placement;cmd > file 2>&1andcmd 2>&1 > filebehave differently because redirections are applied left to right. - Assuming file descriptor numbers are fixed forever in a script; they can be closed, duplicated, and reopened at any point.
- File descriptor 0 is stdin, 1 is stdout, 2 is stderr.
echoandprintfwrite to stdout by default; only explicit redirection sends text to stderr.>&2after a command redirects that command's stdout into stderr.- Redirections are processed left to right, so order matters when combining them.
Chapter Quiz — Complete all 13 topics to unlock
0/13 topics done
Complete these topics first:
- Function Basics
- The read Command and Here-Strings
- Function Arguments
- stdin, stdout, stderr and File Descriptors
- Return Values
- Redirection Operators
- Local Variables
- Pipes and Chaining Commands
- Recursive Functions
- Here-Documents (<<EOF)
- Function Libraries
- The tee Command
- Discarding Output with /dev/null