Wednesday, April 03, 2002

Redirecting Shell Output

Some times when executing commands the output turns out to be too long, making difficult to read it properly. One can "pipe" the output via less, with something of this type:

command | less

However that does not work all the time, so we need to learn how to redirect commands’ output to some files. First of all, there are two types of output, called standard output and standard error. The first one contains the "results" of your command, what you are usually interested on. The error part is precisely for that, for the system to inform you of things that go wrong.

Usually the standard output and errors appear in the terminal. However any of these two outputs can be redirected somewhere else, usually a file. There is a very useful file in the system called /dev/null: whatever is written here gets automatically deleted! If you wonder about the use of it, think of a command that produces a lot of error output; redirecting it to /dev/null erases all errors.

The standard output and error have "nicknames" in the system, namely 1 and 2 respectively (remember file descriptors from C?). We will see in the examples below how to use these short names.

An example of a situation where is useful to delete errors is given by the command find Suppose you are looking for a file called interfaces in the /etc/etc/network/interfaces). One possible way of finding it is with the following command: directory (I have chosen a file that exists in my system,

find /etc -name interfaces

However, executing the command as given above will produce errors: a warning message for each directory in which you are not authorised to look for files. That might be a little distracting, so we redirect the errors to /dev/null to get rid of them:

find /etc -name interfaces 2>/dev/null

The last part says to sent the standard error to /dev/null, so it gets erased. Note: in this case, if there is no file with the name interfaces then you will not get any output: the standard output is empty as there is no such file, the standard error get erased.

A common use of output redirection is to get the "result" of your commands in a file. For example, you might want to list all the files in your account; the output could be long, so you can redirect it to a file, and then look at it carefully. Here is a possible way of doing it:

ls -lR ~ 1>/tmp/log

After executing this command a full list of your files will be available in the file /tmp/log.

Redirection of files is also used when you execute a command that has an output that you need, but the execution takes a long time. Let’s take an "advanced" example (do not worry if you don’t understand the precise command, it is just an example). Suppose you have to execute a make command that takes a long time, say a kernel compilation. You want to keep the output (standard output = 1) and the error (standard error = 2) for future reference. But since hte compilation is going to take time you want to continue using the shell. You can do it like this example, where the "nice" output will go to the file correct.log while the errors get written to incorrect.log:

make 2>incorrect.log 1>correct.log &

The last ampersand (&) says that the shell should execute the command make and continue taking input from your keyboard. If you had not redirected output, but put the ampersand, you can continue working, but the command make will keep writing into your terminal, making life a little complicated :-)