Understanding input and output redirection in bash shell scripts to avoid printing output and errors.

Overview

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.

Concepts

In Linux, everything is a file, even data streams and devices are treated like ordinary files.

There are always three default files open:

stdin
the keyboard
stdout
the screen
stderr
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.

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

Null device

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:

1>/dev/null

Redirect stderr to the null device

2>/dev/null

Redirect both stdout and stderr to the null device

&>/dev/null

Redirect stderr to the same file of stdout

1>/dev/null 2>&1

Examples

Let’s see a simple example with the ls command:


$ 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.

Summary

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.

References

Uruguay
Marcelo Canina
I'm Marcelo Canina, a developer from Uruguay. I build websites and web-based applications from the ground up and share what I learn here.