How to use the POSIX standard file descriptors stdin, stdout and stderr
This concept is older than I am, from times where things were much simpler. You want to figure out what standard input (stdin), standard output (stdout) and standard error (stderr) are? Let’s start with basic concepts:
- Most Linux or Unix systems adhere to the POSIX standard.
- The POSIX standard defines (among other things) three standard file descriptors: stdin, stdout and stderr.
What is a file desciptor?
File descriptors typically have non-negative integer values, with negative values being reserved to indicate “no value” or error conditions. – Wikipedia
To summarise: if you “open” a file, you get an integer back, a file descriptor. Some default file descriptors are usually available. They serve as communication channels between a process and its environment, aka your console/terminal.
file descriptor | name |
---|---|
0 | stdin |
1 | stdout |
2 | stderr |
If you run ls
, it prints the output to your terminal, using stdout.
$ ls -l
total 24
-rw-r--r-- 1 jwb staff 6 5 Nov 00:06 a
-rw-r--r-- 1 jwb staff 20 5 Nov 00:06 b
-rw-r--r-- 1 jwb staff 37 5 Nov 00:07 c
You can also send data to a process via stdin and some commands send error messages to stderr.
Redirection
You can redirect these “streams” to (and from) files or other processes. In bash it looks like this:
# redirect stdin from a file to command; and stdout and stderr of a command to files
command <stdin.txt 2>stderr.txt >stdout.txt
You can even redirect one stream into another. Here we redirect stderr to stdout
which then gets written to stdout_and_stderr.txt
.
command >stdout_and_stderr.txt 2>&1
Be aware, the order is important! The command below sends stdout to the file, but stderr is redirected to stdout.
command 2>&1 >stdout_only.txt
When is this useful? Nearly never, except you want to mute stdout and continue (aka “pipe”, see further below for explanation) with stderr:
command 2>&1 >/dev/null | grep ...
# example:
ls -z 2>&1 >/dev/null | grep invalid
A detailed explanation you can find in the Redirections chapter of the bash manual.
Note that zsh is behaving slightly different. You have to unset the multios option first:
# zsh-specific
unsetopt multios
ls -z 2>&1 >/dev/null | grep invalid
Pipelines
A pipeline is a sequence of one or more commands separated by one of the control operators
|
(the pipe symbol) or|&
. – bash manual
We’ll focus on |
. Here we pipe stdout of 1st command to stdin of 2nd command:
$ cmd1 | cmd2
How can you visualise it?
Of course you can mix and match redirection and pipe operations.
Have fun!