Bash scripting, checking for errors, logging
For logging, you can arrange for all output written on standard output and/or standard error to go to a file. That way, you don't need to redirect the output of each command:
# Save standard output and standard error
exec 3>&1 4>&2
# Redirect standard output to a log file
exec 1>/tmp/stdout.log
# Redirect standard error to a log file
exec 2>/tmp/stderr.log
# Now the output of all commands goes to the log files
echo "This goes to /tmp/stdout.log"
echo "This goes to /tmp/stderr.log" 1>&2
...
# Print a message to the original standard output (e.g. terminal)
echo "This goes to the original stdout" 1>&3
# Restore original stdout/stderr
exec 1>&3 2>&4
# Close the unused descriptors
exec 3>&- 4>&-
# Now the output of all commands goes to the original standard output & error
...
To execute a command only if a previous one succeeds, you can chain them with conditionals:
# Execute command2 only if command1 succeeds, and command3 only if both succeed:
command1 && command2 && command3
# Execute command2 only if command1 fails
command1 || command2
so you can do things like
{ find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" &&
gzip ${TAR} &&
find . -mtime +7 -type f -print0 | xargs -0 rm -f } ||
{ echo "Something failed" 1>&2; exit 1 }
or provide details in the log output:
find . -mtime +7 -type f -print0 | xargs -0 tar -cf "${TAR}" ||
{ echo "find failed!!" 1>&2; exit 1 }
gzip ${TAR} ||
{ echo "gzip failed!!" 1>&2; exit 1 }
find . -mtime +7 -type f -print0 | xargs -0 rm -f ||
{ echo "cleanup failed!!" 1>&2; exit 1}
For logging, you can wrap sections of your script in curly braces and redirect the stdout to a log file:
{
script_command_1
script_command_2
script_command_3
} >> /path/to/log_file
The easy way out, but with no explicit error message add -e
to the shebang, i.e. #!/bin/sh -e
which will cause the shell to exit if a command fails..
Cron should give you an error message through the mail I guess though.
If you want to go full blown back-up scheme though, I'd suggest you use something that has already been made. There are a bunch out there, and most work very well.