
Linux System Programming Techniques
By :

In this recipe, we will learn how to redirect standard input, standard output, and standard error to and from files. Redirecting data to and from files is one of the basic principles of Linux and other Unix systems.
stdin is the shorthand word for standard input. stdout and stderr are the shorthand words for standard output and standard error, respectively.
It's best if we use the Bash shell for this recipe for compatibility purposes.
To get the hang of redirections, we will be performing a bunch of experiments here. We are really going to twist and turn the redirections and see stdout, stderr, and stdin operate in all kinds of ways. Let's get started:
ls
command into a file:$> cd $> ls / > root-directory.txt
cat
:$> cat root-directory.txt
wc
command to count lines, words, and characters. Remember to press Ctrl + D when you have finished typing in the message:$> wc hello, how are you? Ctrl+D 2 4 20
wc
works, we can redirect its input to come from a file instead—the file we created with the file listing:$> wc < root-directory.txt 29 29 177
$> ls /asdfasdf > non-existent.txt ls: cannot access '/asdfasdf': No such file or directory
$> ls /asdfasdf 2> errors.txt
errors.txt
:$> cat errors.txt ls: cannot access '/asdfasdf': No such file or directory
$> ls /asdfasdf > root-directory.txt 2> errors.txt
$> ls /asdfasdf &> all-output.txt
$> wc < all-output.txt > wc-output.txt 2> \ > wc-errors.txt
$> echo hello > /dev/stderr hello
$> echo hello 1>&2 hello
$> (echo hello > /dev/stderr) > hello.txt hello $> (echo hello 1>&2) > hello.txt hello
/dev
directory. This means we can even redirect stdin from a file. This experiment doesn't do anything useful—we could have just typed wc
, but it proves a point:$> wc < /dev/stdin hello, world! Ctrl+D 1 2 14
$> (ls /asdfasdf 2> /dev/stdout) > \ > error-msg-from-stdout.txt $> cat error-msg-from-stdout.txt ls: cannot access '/asdfasdf': No such file or directory
Standard output, or stdout, is where all the normal output from programs gets printed. Stdout is also referred to as file descriptor 1.
Standard error, or stderr, is where all error messages get printed. Stderr is also referred to as file descriptor 2. That is why we used 2>
when we redirected stderr to a file. If we wanted to, for clarity, we could have redirected stdout as 1>
instead of just >
. But the default redirection with >
is stdout, so there is no need to do this.
When we redirected both stdout and stderr in Step 9, we used an &
sign. This reads as "stdout and stderr".
Standard input, or stdin, is where all input data is read from. Stdin is also referred to as file descriptor 0. Stdin redirects with a <
, but just as with stdout and stderr, we can also write it as 0<
.
The reason for separating the two outputs, stdout and stderr, is so that when we redirect the output from a program to a file, we should still be able to see the error message on the screen. We also don't want the file to be cluttered with error messages.
Having separate outputs also makes it possible to have one file for the actual output, and another one as a log file for error messages. This is especially handy in scripts.
You might have heard the phrase "Everything in Linux is either a file or a process". That saying is true. There is no other thing in Linux, except for files or processes. Our experiments with /dev/stdout
, /dev/stderr
, and /dev/stdin
proved this. Files represent even the input and output of programs.
In Step 11, we redirected the output to the /dev/stderr
file, which is standard error. The message, therefore, got printed on standard error.
In Step 12, we pretty much did the same thing but without using the actual device file. The funny-looking 1>&2
redirection reads as "send standard output to standard error".
Instead of using /dev/stderr
, for example, we could have used /dev/fd/2
, where fd stands for file descriptor. The same goes for stdout, which is /dev/fd/1
, and stdin, which is /dev/fd/0
. So, for example, the following will print the list to stderr:
$> ls / > /dev/fd/2
Just like we can send standard output to standard error with 1>&2
, we can do the opposite with 2>&1
, which means we can send standard error to standard output.