redirecting to /dev/null
I’m reading an example bash shell script:
#!/bin/bash
# This script makes a backup of my home directory.
cd /home
# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1
# First remove the old bzip2 file. Redirect errors because this generates some if the archive
# does not exist. Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar
# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1
# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log
I’m trying to understand the use of /dev/null 2>&1
here. At first, I thought this script uses /dev/null
in order to gracefully ignore errors, without causing the script to crash (kind of like try catch exception handling in programming languages). Because I don’t see how using tar to compress a directory into a tar file could possibly cause any type of errors.
I’m trying to understand the use of “> /dev/null 2>&1” here.
(note that I added the redirection before /dev/null
in your question.)
The above would redirect the STDOUT
and STDERR
to /dev/null
. It works by merging the STDERR
into the STDOUT
. (Essentially all the output from the command would be redirected to the null device.)
… without causing the script to crash (kind of like try catch exception handling in programming languages).
It’s not quite like a try/catch
or anything. It simply silences any sort of output (including error) from the command.
Because I don’t see how using tar to compress a directory into a tar
file could possibly cause any type of errors.
It could result in errors for a number of reasons, including:
- Inadequate permissions on the file(s) you’re attempting to archive or on the file that you’re attempting to write to
- Lack of disk space in order to create the archive
No, this will not prevent the script from crashing. If any errors occur in the tar
process (e.g.: permission denied, no such file or directory, …) the script will still crash.
This is because of using > /dev/null 2>&1
will redirect all your command output (both stdout
and stderr
) to /dev/null
, meaning no outputs are printed to the terminal.
By default:
stdin ==> fd 0
stdout ==> fd 1
stderr ==> fd 2
In the script, you use > /dev/null
causing:
stdin ==> fd 0
stdout ==> /dev/null
stderr ==> fd 2
And then 2>&1
causing:
stdin ==> fd 0
stdout ==> /dev/null
stderr ==> stdout
When you run CMD > /dev/null 2>&1
STDOUT redirects to /dev/null, and then STDERR redirects to THE ADDRESS of STDOUT, which has been set to /dev/null , consequently both STDOUT and STDERR point to /dev/null
Oppositely, when you run CMD 2>&1 >/dev/null
STDERR redirects to THE ADDRESS of STDOUT (File descriptor 1 in that moment, or /proc/self/fd/1), and then STDOUT redirects to /dev/null , but STDERR keeps redirecting to fd1!! As a result the normal output from STDOUT is discarded, but the errors coming from STDERR are still being written onto the console.
Bash I/O Redirection
This code:
command > filename 2>&1
> filename
redirectsstdout
tofilename
- (
2>&1
) redirectsstderr
tostdout
(nowfilename
)
(file descriptor 1 is the default, so >
is short for 1>
)
Here is the ABSG explanation (Ch. 20).
Another common example:
command >>/dev/null 2>&1
redirects stderr
and stdout
to /dev/null
… which means to nowhere. Things sent to /dev/null
are not saved, cached, or remembered in any way.
They are just sent to ‘nowhere‘ and forgotten. This is a way of running programs and making sure they produce NO output and will never be seen on the command line or in a log file.
I see this type of question quite a bit … mainly because I’ve had to look it up myself since I haven’t been coding in years. Here is some handy information from the ABSG:
“Redirection simply means capturing output from a file, command, program, or script and sending it as input to another file, command, program, or script.”
2>&1
# Redirects stderr to stdout.
command >>filename 2>&1
# Appends both stdout and stderr
#+ to the file "filename" ...
ABSG: Advanced Bash Scripting Guide: The Chapter 20 link above is a link to the I/O redirection page of the open source tldp.org document called the Advanced Bash Scripting Guide by Mendel Cooper. It is listed as “An in-depth exploration of the art of shell scripting
” and I absolutely agree. It is a terrific resource and has tons of answers to all sorts of crazy situations.
Other Valuable Resources: There are many valuable resources in the current/maintained section (in several handy formats like html, pdf, text, etc) on the Linux Documentation Project Guides page. Here are a few I have found useful:
- Bash Guide for Beginners by Machtelt Garrels
- Introduction to Linux by Machtelt Garrels
- GNU/Linux Command-Line Tools Summary by Gareth Anderson
- Linux Filesystem Hierarchy by Binh Nguyen
- Securing & Optimizing Linux (pdf only): The Ultimate Solution by Gerhard Mourani
To understand "redirecting to /dev/null
" easily, write it out explicitly. Below is an example command that tries to remove a non-existent file (to simulate an error).
rm nonexisting.txt 1> /dev/null 2> /dev/null
- is for stdout. Sends info logs to /dev/null
- is for stderr. Sends error logs to /dev/null
Below are couple of enhancements.
Enhancement 1: You can replace 1>
with just >
. This is because 1
is the default stdout and you can ignore mentioning defaults.
rm nonexisting.txt > /dev/null 2> /dev/null
Enhancement 2: You can replace the 2nd file redirect (> /dev/null
) with a file descriptor duplication (>& 1
). This is because /dev/null
is already pointed to by stdout 1
.
rm nonexisting.txt 1> /dev/null 2>& 1
Enhancement 3: This is such a common operation, that many shells have a shortened form of this as a single &>
operator.
rm nonexisting.txt &> /dev/null
My suggestion: Stick to the first option. Write out the commands explicitly instead of using pointers. Takes little to no extra effort but much easier to understand and explain.
cat nonexistantfile.txt &>/dev/null
This redirects both STDOUT both STDIN
And is equivalent to
cat nonexistantfile.txt >/dev/null 2>&1
instead of using >/dev/null 2>&1
Could you use : -O /dev/null -o /dev/null
what i can see on the other forum serverfault , it says. “Here -O sends the downloaded file to /dev/null and -o logs to /dev/null instead of stderr. That way redirection is not needed at all.”
and the other solution is : -q –spider
https://serverfault.com/questions/619542/piping-wget-output-to-dev-null-in-cron/619546#619546