Skip to content
linux command-line

stdout and stderr

stdout stderr stdin redirection shell
Plain English

Every command line program has two ways to talk back. stdout is for normal results; stderr is for errors and warnings. Both show up in your terminal, so they look the same, but you can send them to different places, such as saving results to a file while errors still appear on screen. There is also stdin, the stream a program reads input from.

Technical Definition

Every Unix process starts with three open file descriptors:

FDNameDefaultPurpose
0stdinkeyboardinput
1stdoutterminalnormal output
2stderrterminalerrors, warnings, progress

Redirection (Bash):

  • cmd > file: stdout to file (overwrite); >> appends
  • cmd 2> file: stderr to file
  • cmd > file 2>&1: both to the same file (order matters: redirect stdout first)
  • cmd &> file: Bash shorthand for both
  • cmd 2> /dev/null: discard errors
  • cmd < file: read stdin from a file

Pipes carry stdout only. cmd | grep x does not search error messages unless you add 2>&1 before the pipe (or use |&).

Why separate streams: a script can capture clean data from stdout while errors still reach a human or a log. Under systemd, both streams from a service go to the journal, and stderr lines can be marked with a higher priority.

Source: bash(1) Linux manual page, REDIRECTION

Redirecting output

# Results to a file, errors still on screen
$ find / -name "*.conf" > confs.txt
find: '/root': Permission denied

# Hide the permission errors
$ find / -name "*.conf" 2>/dev/null | wc -l
412

# Save errors separately
$ find / -name "*.conf" > confs.txt 2> errors.txt

# Everything into one log
$ ./backup.sh > backup.log 2>&1

# Search error output too
$ apt-get install nosuchpkg 2>&1 | grep -i "unable"
E: Unable to locate package nosuchpkg
In the Wild

Redirection shows up in nearly every script and cron job. Cron mails or discards output depending on setup, so most jobs end with >> /var/log/job.log 2>&1 to keep a record. When grep “cannot find” an error you can see on screen, it is almost always on stderr and not reaching the pipe. Do not hide stderr with 2>/dev/null in scripts unless you are sure the errors do not matter.