Each process has an input stream named stdin and two output streams, stdout and stderr . These output streams connect to your terminal, so the following commands will print the string "hello" to your terminal:
printf("hello\n"); fprintf(stdout, "hello\n"); fprintf(stderr, "hello\n");
The first two are exactly the same, the first is simply shorter and more convenient. The first is most commonly used.
The third is different in that the content sent to stderr is logically separate from the content sent to stdout . It is usually used for error messages that you want to see. The perror library perror displays its error messages on stderr .
The meaning of the logically shared stderr stream is that its contents can be separated from stdout . For example, suppose we use the ls -l to display a file.
$ touch myfile $ ls -l myfile -rw-r--r-- 1 wrm staff 0 6 Nov 20:44 myfile
Now, if we redirect the output of ls to another file, we see the following:
$ ls -l myfile > otherfile $
There is no printed output because > redirected the stdout thread of the ls process to otherfile . You can see the redirected output by looking at the otherfile :
$ cat otherfile -rw-r--r-- 1 wrm staff 0 6 Nov 20:44 myfile $
But > did not redirect the stderr stream. You can verify this by removing myfile and restarting the ls -l redirected ls -l :
$ rm myfile $ ls -l myfile > otherfile ls: myfile: No such file or directory $
So you can see that although stdout was redirected to otherfile , stderr not redirected and therefore its contents appeared on the terminal. Also note that otherfile now empty because the ls did not find myfile and therefore there was nothing to send to stdout .
You can also redirect stderr , but it depends on your shell (the program that controls your terminal) how it is done.