Skip to content

armilazarifi/bash-backup-util

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bash-backup-util

A selective, timestamped file backup utility for GNU/Linux, written in Bash.


Description

backup.sh started as a university operating systems assignment and was later improved into a more complete tool. It backs up files matching specified extensions from a source directory into a timestamped folder, compresses each file individually into a .tar.gz archive, optionally encrypts everything with GPG, writes a structured log, and cleans up old backup folders based on a retention policy.

It runs in two modes: interactive (prompts at runtime) and cron/silent (all parameters as arguments, no prompts).

This is a Bash scripting portfolio project, not a replacement for tools like borgbackup, restic, or rsync.


Features

  • Filter files by one or more extensions (e.g. txt, pdf, jpg)
  • Timestamped backup directories — each run is isolated
  • Per-file .tar.gz compression with post-creation integrity check (tar -tzf)
  • Discovered files manifest saved alongside archives
  • Structured backup.log with timing, counts, and encryption status
  • Optional GPG symmetric encryption of all archives
  • Configurable retention policy — removes old backup folders automatically
  • Interactive mode with input validation
  • Cron/silent mode with full argument validation before any files are written
  • Meaningful exit codes for automation and cron monitoring
  • Optional desktop notifications via notify-send

Requirements

Requirement Notes
GNU/Linux Not compatible with macOS or BSD
Bash 4.0+ Uses arrays and [[ ]] syntax
GNU coreutils realpath, date, du
GNU findutils find
tar Compression and integrity checking
gpg Optional — needed only if encryption is enabled
notify-send Optional — desktop notifications on Linux

Installation

git clone https://github.com/armilazarifi/bash-backup-util.git
cd bash-backup-util
chmod +x backup.sh

No dependencies to install. The script runs directly.


Usage

Interactive mode

./backup.sh <source_dir> <dest_dir>

Prompts for extensions, retention days, and encryption choice.

Cron / silent mode

./backup.sh <source_dir> <dest_dir> "<extensions>" <retention_days> <encrypt:y|n> "<passphrase>"

All parameters passed as arguments. No prompts. Pass "" as the passphrase when encryption is off.

Arguments:

Argument Description
source_dir Directory to back up (must exist)
dest_dir Where timestamped backup folders are created
extensions Space-separated extensions, e.g. "txt pdf jpg"
retention_days Remove backups older than this many days (positive integer)
encrypt Enable GPG encryption: y or n
passphrase GPG passphrase — required when encrypt=y, otherwise pass ""

Examples

Back up .txt and .pdf files, no encryption, 7-day retention:

./backup.sh ~/documents /mnt/backup "txt pdf" 7 n ""

Back up .txt files with GPG encryption, 14-day retention:

./backup.sh ~/documents /mnt/backup "txt" 14 y "my_passphrase"

Interactive mode:

./backup.sh ~/documents /mnt/backup

Cron job example (crontab -e):

0 2 * * * /home/user/bash-backup-util/backup.sh /home/user/documents /mnt/backup "txt pdf" 30 n "" >> ~/backup_cron.log 2>&1

See examples/cron_example.sh for a commented cron setup.


Output Structure

Each run creates a timestamped folder inside the destination directory.

Without encryption:

backup_2026_06_22_14_30_00/
├── discovered_files.txt
├── backup.log
├── notes_2026_06_22_14_30_00_1.tar.gz
├── report_2026_06_22_14_30_00_2.tar.gz
└── photo_2026_06_22_14_30_00_3.tar.gz

With GPG encryption — on successful encryption the original .tar.gz is removed, leaving only .tar.gz.gpg files:

backup_2026_06_22_14_30_00/
├── discovered_files.txt
├── backup.log
├── notes_2026_06_22_14_30_00_1.tar.gz.gpg
├── report_2026_06_22_14_30_00_2.tar.gz.gpg
└── photo_2026_06_22_14_30_00_3.tar.gz.gpg

If encryption fails for a specific archive, the original .tar.gz is kept so no data is lost.

discovered_files.txt — files found during the scan, saved before compression starts. Records discovery, not success — a file that disappears mid-run will appear here but be counted as failed in the log.

backup.log — written at the end of each run:

Backup Log
==========
Start time        : 2026-06-22 14:30:00
End time          : 2026-06-22 14:30:02
Duration          : 2s
Source            : /home/user/documents
Extensions        : txt pdf
Backup dir        : /mnt/backup/backup_2026_06_22_14_30_00
Backup size       : 48K
Files found       : 3
Files OK          : 3
Files failed      : 0
Encrypt requested : yes
Archives encrypted: 3
Encryption failed : 0

Exit Codes

Code Meaning
0 Full success
1 Startup error — bad arguments, missing source, or gpg unavailable when encryption is required
2 Compression failures only
3 Encryption failures only
4 Both compression and encryption failures

Useful for monitoring cron jobs or chaining in shell scripts.


Security Notes

  • GPG symmetric encryption is optional and off by default.
  • The passphrase is passed to gpg via stdin (--passphrase-fd 0), not as a command-line argument, so it does not appear in the process list (ps).
  • However, in cron/silent mode the passphrase is a positional argument to the script itself, so it may appear in shell history or /proc/*/cmdline. This is a known limitation of the current cron-mode interface.
  • If gpg is missing and encryption is requested in cron mode, the script exits with code 1 before writing any files. It will never silently fall back to unencrypted output.

Known Limitations

  • GNU/Linux focused — relies on date -d and other GNU-specific behavior that may not work on macOS or BSD.
  • Filenames with literal newlines are not supported by the manifest format.
  • Per-file compression — each file gets its own .tar.gz archive. This makes individual file recovery straightforward, but the backup is not stored as one full-directory archive.
  • No advanced backup features — the script does not provide deduplication, incremental backups, or built-in remote backup targets like dedicated tools such as borgbackup, restic, or rsync.
  • Retention uses mtime — if a backup folder's modification time is changed externally, retention behavior may be affected.

License

MIT

About

Bash backup utility with extension filtering, GPG encryption, retention cleanup, and cron support

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages