A bash script that creates timestamped, compressed backups of a given directory and automatically rotates old archives to stay within a configurable limit.
- Accepts two arguments: an absolute path to the source directory and the maximum number of backups to retain
- Creates the backup destination
/tmp/backups/if it does not exist - Archives and compresses the source directory with
tar+gzip - Names the archive
<dir>-<timestamp>.tar.gz, where/in the path is replaced with-and the leading separator is dropped (e.g./etc/default→etc-default-2026-05-10-120000.tar.gz) - After creating a new backup, deletes the oldest archives for that directory so that no more than n copies remain
- Validates both arguments and prints a descriptive message to stderr with a non-zero exit code on any error
- Each run must either create a backup or display an error message — silent failure is not acceptable.
- The script must validate the argument count and the existence of the source directory. On failure it must write to stderr and exit with a non-zero code.
- Archive name template for rotation:
<archived dirname with dashes>*.tar.gz - The script must be uploaded to a GitHub repository named
task4_3. - The repository must contain exactly one file:
task4_3.shin the root folder.
This section describes how to spin up a local Ubuntu 16.04 environment that matches the grader's setup so you can verify the solution before submission.
Prerequisites: Docker Desktop installed and running.
# 1. Pull the Ubuntu 16.04 image
docker pull ubuntu:16.04
# 2. Start a container
docker run -it --name backup-test ubuntu:16.04 /bin/bashInside the container:
# 3. Install prerequisites
apt-get update && apt-get install -y git
# 4. Clone the repository (replace with your actual URL)
git clone https://github.com/<your-username>/task4_3 /root/task4_3
cd /root/task4_3
# 5. Create a test directory with some content
mkdir -p /tmp/testdir && echo "hello" > /tmp/testdir/file.txt
# 6. Run the backup script — creates the first archive
bash task4_3.sh /tmp/testdir 3
ls /tmp/backups/
# 7. Run twice more to accumulate 3 backups
bash task4_3.sh /tmp/testdir 3
bash task4_3.sh /tmp/testdir 3
ls /tmp/backups/ # should show exactly 3 archives
# 8. Run a fourth time — the oldest archive must be deleted
bash task4_3.sh /tmp/testdir 3
ls /tmp/backups/ # still exactly 3 archives
# 9. Test error cases
bash task4_3.sh # too few args → exit 1
bash task4_3.sh /no/such/dir 3 # missing dir → exit 2
bash task4_3.sh /tmp/testdir abc # invalid count → exit 3
bash task4_3.sh /tmp/testdir 3 extra # too many args → exit 1To re-use the container later:
docker start -ai backup-testTo start fresh:
docker rm backup-testPrerequisites: VirtualBox and Vagrant installed.
Create a Vagrantfile in any working directory:
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y git
SHELL
end# Start and SSH into the VM
vagrant up
vagrant ssh
# Then follow steps 4–9 from Option A above (inside the VM)
sudo -i
git clone https://github.com/<your-username>/task4_3 /root/task4_3
cd /root/task4_3
bash task4_3.sh /tmp/testdir 3| Check | Command | Expected result |
|---|---|---|
| Backup dir created automatically | bash task4_3.sh /tmp/testdir 3 && ls /tmp/backups/ |
Directory exists, archive present |
| Archive filename format | ls /tmp/backups/ |
Matches tmp-testdir-<timestamp>.tar.gz |
| Archive is valid gzip | file /tmp/backups/tmp-testdir-*.tar.gz |
gzip compressed data |
| Rotation keeps exactly n files | Run script 4× with limit 3, then ls /tmp/backups/ | wc -l |
3 |
| Too few arguments | bash task4_3.sh /tmp/testdir |
Prints error to stderr, exits 1 |
| Too many arguments | bash task4_3.sh /tmp/testdir 3 extra |
Prints error to stderr, exits 1 |
| Non-existent source directory | bash task4_3.sh /no/such/dir 3 |
Prints error to stderr, exits 2 |
| Non-numeric backup count | bash task4_3.sh /tmp/testdir abc |
Prints error to stderr, exits 3 |
- OS: Ubuntu Xenial 16.04 Server
- User:
root - Network: internet access available
- The repository is cloned by URL (e.g.
https://github.com/user/task4_3); a different repository name results in automatic failure. task4_3.shis launched automatically from the repository root; a different script name or subdirectory location results in automatic failure.- The script is run with multiple parameter combinations covering all error and success cases listed below.
/tmp/backups/is created if it does not exist.- A new archive is created at
/tmp/backups/<dir>-<timestamp>.tar.gz. - After creation, archives for the given source directory are counted; any beyond the specified limit are deleted, oldest first.
- The script exits with code
0.
- Message printed to stderr.
- Script exits with a non-zero code.
- No backup is created.
- Message printed to stderr.
- Script exits with a non-zero code.
- No backup is created.
- Message printed to stderr.
- Script exits with a non-zero code.
- No backup is created.
Note: All error messages must go to stderr. Output sent to stdout will not be detected by the checker and the script will be considered non-compliant.