I wrote a Bash script to create a full snapshot of several source directories under a timestamped destination. For now, the source and backup paths can be hard-coded. The script checks whether each source exists, copies it with rsync, logs the rsync output, and then compares the copied directory with the source using diff. I also enabled strict-mode options so that failures should stop the backup. Are there any logic or reliability issues I should fix?
2 Answers
The basic flow is reasonable, but decide whether every error should stop the entire run or whether you want to record failures and continue. At the moment, a missing source is skipped, while a failed rsync or an unhandled diff status can terminate the script. You may also want to verify the rsync exit status explicitly and make sure the destination is created before copying. If preserving all metadata matters, check whether the archive options you use cover the permissions, ownership, timestamps, ACLs, extended attributes, and links you need; -a alone does not preserve every kind of metadata.
The shebang needs to be the very first line. If it appears after another comment, it is treated as an ordinary comment, and running the file may use whatever shell launches it. That matters here because arrays and pipefail require Bash. Also, with set -e enabled, diff returns status 1 when it finds differences, so the script will stop at the first mismatch and never process later sources. Handle that status explicitly, for example with diff -r ... || echo "Mismatch found". For large directory trees, a checksum-based rsync dry run such as rsync -anci "$SRC/" "$DESTINATION/" may be a more targeted verification than recursively running diff.

The misplaced shebang was just an editing oversight. I did want the script to stop if the backup was incomplete, but I hadn't considered that diff uses status 1 to report ordinary differences rather than a command failure. The rsync verification approach should also be more practical for my larger backup trees.