Assignment 2: A safe backup/parameterised script
Goal: Write a robust, parameterised Bash script that backs up a directory into a timestamped compressed archive, validates its inputs, is safe to re-run, and cleans up after itself.
Where: On the Jumpbox (10.100.100.254, Ubuntu, user ubuntu). Create ~/backup.sh and back up something harmless you own, such as ~/scripts or a test folder you create.
Tasks
- Create
~/backup.shwith the shebang#!/usr/bin/env bash, the safety headerset -euo pipefail, and a header comment showing usage:Usage: ./backup.sh <source-dir> [dest-dir]. - Arguments & validation: Read the source directory from
$1and an optional destination from$2(default the destination to~/backups). If no source is given, print the usage line to stderr andexit 1. If the source is not an existing directory (-d), print an error to stderr and exit non-zero. - Add a
die()helper that printsERROR: <message>to stderr and exits 1, and use it for your validation messages. - Idempotent destination: Create the destination directory with
mkdir -p "$dest"so re-running never errors. - Timestamped archive: Build an archive name that includes the source's basename and a timestamp, e.g.
scripts-2026-06-01_142530.tar.gz(hint:date +%F_%H%M%S). This guarantees each run makes a new file rather than overwriting an old backup. - Create the backup: Use
tar -czf "$dest/$archive" -C "$parent" "$base"to compress the source. Capture/print the resulting file size (e.g.du -h "$dest/$archive"). - trap cleanup: If you build the archive via a temporary file or staging area, register
trap 'rm -f "$tmp"' EXITso partial files are cleaned up if the script fails partway. - Report: Print a clear success line:
Backup complete: <path> (<size>). Exit0on success. - Make it executable, run it against a real folder, then run it a second time to prove it is idempotent (no errors, a new timestamped file appears).
- Run
shellcheck ~/backup.shand resolve all warnings.
Deliverable
The file ~/backup.sh on the Jumpbox: executable, ShellCheck-clean, parameterised, input-validated, idempotent, with a trap and a die() helper. Show your mentor the directory listing of ~/backups after running the script twice (two timestamped archives).
Acceptance criteria — you're done when:
- The script starts with
#!/usr/bin/env bashandset -euo pipefail. - Running it with no arguments prints a usage message to stderr and exits non-zero.
- Running it with a non-existent source directory prints an error to stderr and exits non-zero.
- A valid run creates
~/backupsif missing and writes a.tar.gzwhose name contains the source name and a timestamp. - Running the script twice in a row succeeds both times and produces two distinct archive files (proving idempotency).
- The archive actually contains the source files (verify with
tar -tzf <archive> | head). - A
trapis registered for cleanup, and adie()helper handles error exits. -
shellcheck ~/backup.shreports no warnings, and every variable is double-quoted.
Hints
- Default the destination:
dest="${2:-$HOME/backups}". - Split a path:
base="$(basename "$src")"andparent="$(dirname "$src")"; thentar -C "$parent" "$base"archives clean relative paths instead of absolute ones. - Make a safe temp file with
tmp="$(mktemp)"and remove it via the trap — never hardcode/tmp/backup. - Verify an archive without extracting:
tar -tzf "$dest/$archive" | head. - Re-read Lesson 4 (arguments and functions) and Lesson 5 (set -euo pipefail, trap, idempotency, ShellCheck).
- Test on a throwaway folder first (
mkdir -p ~/testdir && touch ~/testdir/a ~/testdir/b) so you never risk real data.
Blocked for more than ~30 minutes after re-reading the lessons? Bring what you've tried to your mentor.
No comments to display
No comments to display