Standard Input (STDIN), Output (STDOUT), and Error (STDERR) Explained (part 1)

For a lot of people, STDIN (standard input), STDOUT (standard output), and STDERR (standard error) are one of the most confusing subjects. Hopefully, in this post, I can explain once and for all the concepts.

In UNIX you might have heard people mention that everything is a file. Well that is close to correct. I would say that in UNIX everything is defines around file descriptors or FD.

A file descriptor or FD, is a unique identifier referred to as a handle, which identifies a file, an input/output resource, network resource, etc. It is normally a positive number that starts from 0 zero. In UNIX, every process gets, at the very least, 3 file descriptors:

0 = Standard Input
1 = Standard Output
2 = Standard Error

Most commands in UNIX conforms to the standards, including STDIN, STDOUT, and STDERR. The developer writing the code has to conform to the standards. For example: if the program is receiving input from another program, such input is read by using STDIN, if output has to be written to the console or to another program, STDOUT is used, if an error condition has to be written to the console or to another program, STDERR is used.

Let’s examine a practical example by using the “ls” command. Ls without any arguments, lists the files in the current directory. If you type “ls” and press enter, you will receive the listing of that directory via STDOUT. For example:

bin Documents Pictures public_html Video tmp

The ls command also take arguments, one of the argument is the file or the files to list. For example if you type “ls tmp“, you will receive the content of the tmp directory written to STDOUT.

But Wait! What about STDERR? We have not caused any error condition to cause STDERR to be used. Now let’s cause an error condition like invoking the ls command with a non-existent file “ls not-there“, we would get the following output written to STDERR:

ls: cannot access ‘not-there’: No such file or directory

The error message listed above was printed to STDERR. Now you should ask yourself, how do we know for a fact that ls is using STDOUT and STDERR? We would capture that file descriptor and redirect it to a file. Do not worry too much about redirection, I will write a post dedicated to it, for now consider it as capturing.

Let’s now write the following command:

ls > /tmp/stdout.txt

As you can see, we get nothing back, STDOUT has been redirected to a file named /tmp/stdout.txt. If we now type the command:

cat /tmp/stdout.txt

We will get:

bin
Documents
Pictures
public_html
Video
tmp

Are you with me? Great! Let’s continue, it gets more interesting. Now, let’s type the following command:

ls not-there > /tmp/stdout.txt

We now get back the same message as before:

ls: cannot access ‘not-there’: No such file or directory

But why didn’t the output end up in the file? Because the command “ls not-there > /tmp/stdout.txt” only captures STDIN or file descriptor 1. When no number is specified before the redirection > defaults to 1 (STDIN). In order to capture STDERR, we have to capture file descriptor 2, by writing the following command:

ls not-there > /tmp/stdout 2> /tmp/stderr.txt

Now we see nothing, and the error message is redirected to the file /tmp/stderr.txt. If you type the command “cat /tmp/stderr.txt“, you will see the same error message.

Are you still with me? Great! Just to clarify things, we could have also wrote the command as:

ls not-there 1> /tmp/stdout 2> /tmp/stderr.txt

The same result is achieved. Hope you are still with me. But, what if I want to redirect STDOUT and STDERR into the same file? We can use a redirection to a file descriptor. This is simpler shown than explained. Let’s type the following command:

ls not-there 1> /tmp/stdout 2>&1

Still no output is displayed, STDERR is redirected to file descriptor 1 (&1), which ends up redirected to a file /tmp/stdout.txt. Now the file /tmp/stdout.txt contains both STDOUT and STDIN.

cat /tmp/stdout.txt

produces:

ls: cannot access ‘not-there’: No such file or directory

At this point, STDOUT and STDERR should be clearer.

In part 2, we will discuss STDIN, which is going to be just as long and interesting post as this one.

Have fun and type away!!!

Leave a Reply