Understanding input and output redirection in bash shell scripts to avoid printing output and errors.
In shell scripting, you often want to avoid printing error messages to the console or discard any possible output the script could generate. Capturing program output can be done with I/O Redirection in Linux.
In Linux, everything is a file, even data streams and devices are treated like ordinary files.
There are always three default files open:
- the keyboard
- the screen
- error messages output to the screen
Output from these files can be captured and sent as input to another file, command, program or script. This is called redirection.
How do you choose what file to handle? With file descriptors.
A file descriptor is simply a number that the operating system assigns to an open file to keep track of it. Consider it a simplified type of file pointer. It is analogous to a file handle in C.
Kowing the file descriptors of each file, we can select with which one we want to work and process redirection between them.
The file descriptors for our open files are:
- stdin: 0
- stdout: 1
- stderr: 2
Then we can use
M>N in each command to redirect the file descriptor
M to N:
- M: file descriptor, which defaults to 1, if not explicitly set.
N can be:
- N: filename,
- &N: another file descriptor
Linux has a special device file that discards all data written to it. In Linux this device is /dev/null.
Redirect to the null device.
The way to discard commands output and error messages is to redirect them to the null device.
This can be done explicitely redirecting both output and/or errors in many ways:
Redirect stdout to the null device:
Redirect stderr to the null device
Redirect both stdout and stderr to the null device
Redirect stderr to the same file of stdout
Let’s see a simple example with the
$ ls >/dev/null
stdout file descriptor isn’t present so it defaults to 1, any error would be echoed to the screen.
$ ls -error 1>/dev/null ls: invalid option -- 'e' Try 'ls --help' for more information.
we only redirect stdout but we still see the error generated by the command.
$ ls -error 2>/dev/null
we produce an error with
ls but redirects the error output to the
null device, so we don’t see any output in the screen.
$ ls -error &>/dev/null $ ls &>/dev/null
we avoid outputting errors and the standard command output.
Understanding file descriptors is key to handle commands output and errors.
This is a common practice to avoid outputting anything in cronjobs where the output would be sent to the users email.
Additionally, it is very useful to work with bash redirection not only to the null device.