I’m having trouble getting the command to send standard error to standard out. I intend to put it in cron, but for now am just running manually.
/home/backups/backup_scripts/backup.sh 2>&1 >> /var/log/backups/backup.log
I was hoping the log file would contain any messages that were printed to standard out, but the log file only showed standard out, and the console output showed the errors.
What am I doing wrong here?
This happened because of the order of the redirections. The
2>&1means “redirect standard error to the current location of standard out”. They are processed left to right so first standard error is redirected to the current standard out (still the terminal) then standard out is redirected to a file. If you switch the order to readit should do what you want. If your shell is bash it has a shortcut to redirect standard out and standard error at the same time:
command &> fileredirects them both to a file andcommand &>> fileappends both to a file. This order dependency is also mentioned in the bash manualI think there is some misunderstanding of how file descriptors and redirection works. The kernel has a big table of all the open files on the system that contains the file offset, status flags, and the name of the file itself. Then each process has a table that maps file descriptor numbers to the entries in this global table.
Before any redirections happen the global table might look something like this
and the process table looks like
since descriptor numbers 0, 1, and 2 are stdin, stdout, and stderr respectively.
Then the
2>&1redirection is processed. This changes the process table so that 2 contains points to the same global entry as 1. However, they are already the same so nothing happens.When the
>> /var/log/backups/backup.logredirection is processed. First the file is opened and assigned to file descriptor 3 in the process table so the tables look likeand
then standard out is changed to point to the newly opened file (as if
1>&3were done) so the process table is nowNote that 2 (stderr) is still pointing to the terminal.
When the redirections are done in the other order, the table after
>> /var/log/backups/backup.loglooks the same.and then the
2>&1redirection changes what 2 points to givingso now stdout and stderr both go to the file.