default_generations=0
default_target="/var/backups"
+# Set shell options.
+shopt -s nullglob
+set -o pipefail
+
# Search configuration file (last one is used as default!)
for conf in \
"/usr/local/etc/backup-script.conf" \
done
Usage() {
- echo "Usage: $NAME [-q|--quiet] [-v|--verbose] [<system> [<system> [...]]]"
+ echo "Usage: $NAME [-q|--quiet] [-v|--verbose] [<job> [<job> [...]]]"
echo " $NAME <-d|--dirs> <dir1> <dir2>"
echo
+ echo " -d, --dirs Compare two backup directories (not jobs)."
+ echo " -q, --quiet Quite mode, only list jobs with changes or errors."
+ echo " -v, --verbose Verbose mode, show all checks that are run."
+ echo
+ echo "When no <job> is given, all defined jobs are checked."
+ echo
exit 2
}
:
}
+ListDirectory() {
+ local base_dir="$1"
+ local dir_name="$2"
+
+ local exclude
+
+ exclude='total '
+ if [[ "$dir_name" == "/" ]]; then
+ exclude="$exclude"'| \.stamp$| dev$| etc$| proc$| root$| run$| sys$| tmp$'
+ exclude="$exclude"'| data$| net$| srv$'
+ exclude="$exclude"'| [[:alnum:]_-]+\.log(\.[[:alnum:]]+|)$'
+ fi
+
+ # shellcheck disable=SC2012
+ ls -Al "$base_dir$dir_name" 2>/dev/null \
+ | egrep -v "($exclude)" | awk '!($2="")' | column -t
+}
+
HandleSystem() {
local fname="$1"
/etc/gshadow \
\
/boot/grub/grub.cfg \
+ /etc/aliases \
/etc/bash.bashrc \
+ /etc/crontab \
+ /etc/environment \
/etc/fstab \
/etc/hostname \
/etc/hosts \
+ /etc/hosts.allow \
+ /etc/hosts.deny \
+ /etc/inittab \
+ /etc/ld.so.conf \
+ /etc/login.defs \
/etc/machine-id \
/etc/modules \
/etc/network/interfaces \
/etc/rc.local \
/etc/resolv.conf \
/etc/services \
+ /etc/shells \
+ /etc/ssh/sshd_config \
+ /etc/sshd_config \
/etc/sudoers \
/etc/sysctl.conf \
; do
[[ -r "${gen1_d}${file}" ]] || continue
[[ $VERBOSE -ne 0 ]] && echo "Checking \"$file\" ..."
- diff -U 3 "${gen1_d}${file}" "${gen2_d}${file}" >"$tmp_diff"
- if [[ $? -ne 0 ]]; then
+ if ! diff -U 3 "${gen1_d}${file}" "${gen2_d}${file}" >"$tmp_diff"; then
BeginDiff "\"$file\""
tail -n +3 "$tmp_diff" | PipeDiff
EndDiff
fi
done
+ for dir in \
+ / \
+ /etc/cron.d/ \
+ /etc/cron.daily/ \
+ /etc/cron.hourly/ \
+ /etc/cron.monthly/ \
+ /etc/cron.weekly/ \
+ /etc/sudoers.d/ \
+ /var/log/dumps/ \
+ ; do
+ [[ ! -d "${gen1_d}${dir}" ]] && continue
+ [[ ! -d "${gen2_d}${dir}" ]] && continue
+
+ # Make sure that this is a system root; comparing other
+ # root folders results in misleading output ...
+ [[ "$dir" == "/" && ! -d "${gen1_d}${dir}/etc" ]] && continue
+
+ [[ $VERBOSE -ne 0 ]] && echo "Checking \"$dir\" ..."
+ ListDirectory "${gen1_d}" "${dir}" >"$tmp_1"
+ ListDirectory "${gen2_d}" "${dir}" >"$tmp_2"
+ if ! diff -U 0 "$tmp_1" "$tmp_2" >"$tmp_diff"; then
+ BeginDiff "\"$dir\" directory"
+ tail -n +3 "$tmp_diff" | egrep -v '^@@ ' | PipeDiff
+ EndDiff
+ return_code=1
+ fi
+ done
+
if [[ -d "${gen1_d}/var/lib/dpkg/info" && -d "${gen2_d}/var/lib/dpkg/info" ]]; then
[[ $VERBOSE -ne 0 ]] && echo "Checking list of installed packages ..."
chroot "${gen1_d}" dpkg --get-selections >"$tmp_1" || return 2
chroot "${gen2_d}" dpkg --get-selections >"$tmp_2" || return 2
- diff -U 0 "$tmp_1" "$tmp_2" >"$tmp_diff"
- if [[ $? -ne 0 ]]; then
+ if ! diff -U 0 "$tmp_1" "$tmp_2" >"$tmp_diff"; then
BeginDiff "list of installed packages"
tail -n +3 "$tmp_diff" | grep -v '^@@ ' | PipeDiff
EndDiff
# scp Backup type
file=$(basename "$files")
[[ $VERBOSE -ne 0 ]] && echo "Checking \"$file\" ..."
- diff -U 3 "${gen1_d}/${file}" "${gen2_d}/${file}" >"$tmp_diff"
- if [[ $? -ne 0 ]]; then
+ if ! diff -U 3 "${gen1_d}/${file}" "${gen2_d}/${file}" >"$tmp_diff"; then
BeginDiff "\"$file\""
tail -n +3 "$tmp_diff" | PipeDiff
EndDiff
shift
[[ $# -eq 2 ]] || Usage
MkTempFiles
- DiffGenerations "$default_backup_type" "$1/" "$2/" "$default_files"
+ DiffGenerations "$default_backup_type" "$1" "$2" "$default_files"
return_code=$?
CleanUp
exit $return_code
;;
esac
- HandleSystem "$fname" >"$tmp_out" 2>&1
- [[ $QUIET -eq 0 || $? -ne 0 ]] && cat "$tmp_out"
+ HandleSystem "$fname" >"$tmp_out" 2>&1; result=$?
+ [[ $QUIET -eq 0 || $result -ne 0 ]] && cat "$tmp_out"
done
CleanUp