In Linux, standard streams are channels that ensure a command can receive input and also present its output.
The input stream, known as the standard input (stdin), is responsible for feeding the command its input data. On the other hand, there are two output streams: standard output (stdout) and standard error (stderr). A command writes its output to the stdout stream while it writes the error messages to the stderr stream. It’s important to note that stdout and stderr are independent of one another despite both of them being output streams.
In this tutorial, we’ll focus on the standard error and how to store its data in a Linux variable.
2. Redirecting stderr
Before we proceed, we need to remember Linux treats everything as a file, including the standard streams.
Linux assigns each open file a unique number known as a file descriptor. This is an identifier that Linux processes use to access files associated with it:
- 0 – standard input
- 1 – standard output
- 2 – standard error
In particular, when we execute a command, the file descriptor 2 (stderr) receives the error messages while the file descriptor 1 (stdout) receives the non-error output. Moreover, the terminal usually displays the data from both output streams:
$ ls baeldung Desktop ls: cannot access 'baeldung': No such file or directory Desktop: article.txt history.txt project.pdf test.sh baeldung.txt 'PROGRAMMING PROJECTS' PYTHON
Above, we’re trying to list all directories or files in both the baeldung and Desktop directories. Since baeldung doesn’t exist, we get an error message; since Desktop exists, we get a successful list output.
Next, for clarity, let’s redirect the error message to a file named error.txt. For this, we’ll use the redirecting symbol (>):
$ ls baeldung Desktop 2>errors.txt Desktop: article.txt history.txt project.pdf test.sh baeldung.txt 'PROGRAMMING PROJECTS' PYTHON
From the example above, the error message is missing from the terminal results:
$ cat errors.txt ls: cannot access 'baeldung': No such file or directory
Consequently, when we view the errors.txt file using the cat command, we see that its content is the exact error message that was previously displayed in our terminal.
Let’s now look at command substitution to store the stderr in a Linux variable.
3. Command Substitution to Store stderr in a Linux Variable
Command substitution ($()) ensures that we can execute a command and then save the output to a variable.
First, let’s implement command substitution with the same command we used in the previous section:
$ ERROR=$(ls baeldung Desktop) ls: cannot access 'baeldung': No such file or directory
In this example, we’re trying to store the output from our command to the $ERROR variable. As a result, the error message is displayed in the terminal while the output is not. This happens because command substitution works with only the standard output. Thus, only the stdout was stored in the variable.
Now, when we use the echo command to print out the contents stored in our variable, we get the non-error output:
$ echo $ERROR Desktop: article.txt baeldung.txt history.txt PROGRAMMING PROJECTS project.pdf PYTHON test.sh
Next, let’s redirect the stderr to the stdout:
$ ERROR=$(ls baeldung Desktop 2>&1)
Above, we’re instructing the shell, with (2>&1), to redirect the standard error (2) to the same place as the standard output (1):
$ echo $ERROR ls: cannot access 'baeldung': No such file or directory Desktop: article.txt baeldung.txt history.txt PROGRAMMING PROJECTS project.pdf PYTHON test.sh
As a result, our variable now stores both output streams.
Finally, let’s discard the standard output to only remain with the stderr:
$ ERROR=$(ls baeldung Desktop 2>&1 > /dev/null)
For the above to be possible, we redirect the stdout to /dev/null, a null device file in Linux that buries any data sent to it:
$ echo $ERROR ls: cannot access 'baeldung': No such file or directory
As we conclude this section, we see that the error message is now stored successfully in our $ERROR variable.
In this article, we detailed the basics of redirecting stderr and implemented this knowledge with command substitution to store stderr in a Linux variable.