stdin, stdout, stderr redirection

Someone asked me about this the other day, so here is a rough recap of my explanation. When a UNIX program is run, stdin, stdout and stderr are created automagically. They are standard file streams and can be used for piping or redirection. stdin is “standard input”, stdout is “standard output” and stderr is “standard error”.

stdin, stdout, stderr

The file descriptors are automatically numbered 0, 1 and 2: as in stdin, stdout and stderr. stdin accepts input. The input can be from the terminal or an output from another program. stdout “produces” output from the command. This can be echoed back to the display screen or used as input stream for another program. stderr is meant for errors emitted from the program. Those, of course are predefined uses. There is nothing stopping you from using stderr as stdout.

[admin@build01 ~]$ ps -ef | grep bash
admin    2527817 2527816  0 23:34 pts/0    00:00:00 -bash
[admin@build01 ~]$ cd /proc/2527817/fd
[admin@build01 fd]$ ls -l
total 0
lrwx------. 1 admin admin 64 Nov 30 23:42 0 -> /dev/pts/0
lrwx------. 1 admin admin 64 Nov 30 23:42 1 -> /dev/pts/0
lrwx------. 1 admin admin 64 Nov 30 23:42 2 -> /dev/pts/0
lrwx------. 1 admin admin 64 Nov 30 23:42 255 -> /dev/pts/0
lr-x------. 1 admin admin 64 Nov 30 23:42 3 -> /var/lib/sss/mc/passwd

You might notice file descriptors 3 and 255. Here and here is more info on what those are.

Let’s cat a file:

[admin@build01 ~]$ cat file.txt
This is a text file.

The file is displayed via stdout. We can supply file.txt as input to cat command and redirect output to newfile.txt:

[admin@build01 ~]$ cat < file.txt > newfile.txt
[admin@build01 ~]$ cat newfile.txt
This is a text file.

Let’s say there is nonexistent file nofile.txt:

[admin@build01 ~]$ cat nofile.txt
-bash: nofile.txt: No such file or directory

The error was displayed via stderr. Let’s assume we want to capture the errors in a separate file:

[admin@build01 ~]$ cat nofile.txt 2> error.txt
[admin@build01 ~]$ cat error.txt
cat: nofile.txt: No such file or directory

2 means to redirect stderr to error.txt. To redirect stdout of a command one would do something like: somecommand > output.txt. That is the same as:

[admin@build01 ~]$ cat file.txt 1> redirect.txt
[admin@build01 ~]$ cat redirect.txt
This is a text file.

Notice the 1. Sometimes you do not want to see error messages showing on the screen so we can redirect stderr to /dev/null:

[admin@build01 ~]$ cat nofile.txt 2> /dev/null
[admin@build01 ~]$

The following is sometimes used in cron jobs. A script is run, that has some output going to stdout but in between, you might have some messages emitted to stderr. You might not want to be notified by cron about the outputs, so you can redirect stderr to stdout to /dev/null:

[admin@build01 ~]$ cat nofile.txt > /dev/null 2>&1
[admin@build01 ~]$

2>&1 means redirect stderr to stdout. So, for example if you had 3>&2, that would mean to redirect file descriptor 3 to stderr. If you omited & then the redirect would go to file called 2. & sign can be thought of as “file descriptor”.

Advanced Bash-Scripting Guide has some good info, too.