Every now and then I have a need to redirect all output, both standard and error, within a shell script (bash) to a file. There are two ways — the obvious beginners’ one and the elegant gurus’ one.
For starters let’s have a very simple script test.sh
that generates both standard output (stdout
) and error message (stderr
):
#!/bin/sh echo "Going to run /non/existent" /non/existent
That will produce an expected result when run:
~$ ./test.sh Going to run /non/existent ./test.sh: line 4: /non/existent: No such file or directory ~$
Now the question is how to redirect both messages into a logfile? The poor man’s approach is to create a wrapper-script test-wrapper.sh
:
#!/bin/sh exec ./test.sh > test.log 2>&1
Running that will send all the output into test.log
logfile:
~$ ./test-wrapper.sh ~$ cat test.log Going to run /non/existent test.sh: line 4: /non/existent: No such file or directory ~$
Works a treat, but do we really need two scripts to solve such a simple problem? Of course we don’t. Let’s modify test.sh
this way:
#!/bin/sh exec > test2.log exec 2>&1 echo "Going to run /non/existent" /non/existent
Run it and enjoy the output redirected to a log file test2.log
:
~$ ./test.sh ~$ cat test2.log Going to run /non/existent ./test.sh: line 7: /non/existent: No such file or directory ~$
VoilĂ , here you go. Self contained script that sets up the redirection internally. No need for stupid wrappers anymore