Using ‘/dev/null’ with stdout and stderr to discard unecessary outputs
This is a post regarding /dev/null
known as the blackhole of linux where everything we sent to is discarded. So, we will be looking into how we can discard the unnecessary messages from stdout
and stderr
during command execution that clutter the terminal. Also, to separate the streams into independent files.
Prerequisites:
- Basic linux knowledge
- Different streams in linux i.e
stdout
,stderr
- Redirection
Explanation:
stdout
is the place where all the normal output goes. That is the same case for the stderr
. If it’s not caught or redirected, by default, they
go to the terminal screen.
Streams
0 -> Standard Input (stdin)
1 -> Standard Output (stdout)
2 -> Standard Error (stderr)
Let us take an example of a script:
#!/bin/bash
function get_latest_version() {
echo "Resolving Host" 1>&2
echo "Starting connection" 1>&2
echo "Downloading JSON" 1>&2
echo "Extracting version"
echo "3.2.28"
echo "Linux Redirection Test"
}
# 1 print everything both stdout as well as sterr
echo "the current version of foo is $(get_latest_version)"
# 2 redirect stdout stream to stderr stream
echo "the current version of foo is $(get_latest_version 1>&2 )"
# 3 redirect stdout stream to /dev/null | only print stderr
echo "the current version of foo is $(get_latest_version 1>/dev/null)"
# 4 redirect stderr stream to /dev/null | only print stdout
echo "the current version of foo is $(get_latest_version 2>/dev/null)"
# 5 redirect stdout stream to output_log.txt file and stderr stream to error_log.txt file
echo "the current version of foo is $(get_latest_version 2>error_log.txt 1>output_log.txt)"
## 6 watch the order of streams being redirected
# 1 redirect stderr to /dev/null and stdout to stderr resulting in both streams being redirected to /dev/null
echo "the current version of foo is $(get_latest_version 2>/dev/null 1>&2)"
# 2 redirect stdout to stderr | at this point stderr is pointing to its default destination so stdout is printed then finally stderr is then redirected to /dev/null
echo "the current version of foo is $(get_latest_version 1>&2 2>/dev/null)"
You can try this example by cloning from github repo
Script Breakdown
So, we have got a function get_latest_version
which contains a lot of echo commands. By default, the echo
command prints to the stdout stream and we see the result in the terminal. On contrast, when we use 1>&2
, it redirects the stdout stream to the error stream. So, the function get_latest_version
has both stdout
as well as stderr
streams to be precise 3 each.
As mentioned previously, by default both stdout
and stderr
streams are outputed to the terminal. So,
- After the
#1
command execution, everything is outputed to the screen both thestdout
andstderr
stream.
Resolving Host ->2
Starting connection ->2
Downloading JSON ->2
the current version of foo is Extracting version ->1
3.2.28 ->1
Linux Redirection Test ->1
- After the
#2
,stdout
stream is redirected tostderr
and finallystderr
is outputed to the terminal
Resolving Host ->2
Starting connection ->2
Downloading JSON ->2
Extracting version ->1
3.2.28 ->1
Linux Redirection Test ->1
the current version of foo is
We can see in both cases, everything is outputed in the terminal. Having said that I still have confusion regarding why there is difference in order of echos the current version of foo is
being printed in the terminal.
- After the
#3
,stdout
is redirected to/dev/null
so, only thestderr
is outputed.
Resolving Host ->2
Starting connection ->2
Downloading JSON ->2
the current version of foo is
- After the
#4
,stderr
is redirected to/dev/null
so, only thestdout
is outputed.
the current version of foo is Extracting version ->1
3.2.28 ->1
Linux Redirection Test ->1
- After the
#5
,stdout
is redirected to fileoutput_log.txt
andstderr
is redirected to fileerror_log.txt
. This enables us to view output and error in their respective files making debugging easier.
the current version of foo is
-
- After the
#6.1
, firststderr
is redirected to/dev/null
and then,stdout
is redirected tostderr
. This enables redirecting both thestdout
andstderr
streams to/dev/null
.
- After the
the current version of foo is
This can also be used to redirect both stdout
and stderr
in the same file.
echo "the current version of foo is $(get_latest_version 2>log.txt 1>&2)"
-
- After the
#6.2
, here notice the execution order of2>/dev/null
and1>&2
is reversed. You may be thinking they are almost similar and this should also give same result as#6.1
. But that is not the case. Here,1>&2
redirectsstdout
to wherestderr
is set to at that point and at that point you haven’t redirectedstderr
yet. So,stdout
outputs to stderr’s default direction which isterminal
. Then, later you redirect stderr to/dev/null
. So,stdout
is printed in the terminal and only thestderr
is discarded to/dev/null
.
- After the
Extracting version ->1
3.2.28 ->1
Linux Redirection Test ->1
the current version of foo is
Key TakeWays:
stdout
andstderr
streams can be separated into independent files enabling easier debugging of issues.stdout
andstderr
streams can be discarded to the/dev/null
to declutter the terminal output during script execution`
To Be Explored
We can see the output of the current version of foo is
being at different places. Sometimes, at the top, at the middle and at the bottom, find out why does this happen.