Skip to content

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

backup

A Bash script for backing up a macOS home directory with rsync.

  • Regular files and folders are copied unless backup.ignore excludes them, except inside keep-only areas.
  • Hidden files and folders are skipped unless backup.allow includes them.
  • backup.ignore takes precedence over backup.allow.

The script also supports dry runs, traversal limits, resumable partial transfers, and per-run logs.

Requirements

  • macOS
  • The Bash version included with macOS
  • rsync 3.1 or newer

Install a newer rsync with:

brew install rsync

Protected locations such as Desktop and Documents may require Full Disk Access for the terminal running the script.

Usage

./backup.sh ~ "/Volumes/Backup Disk/home"
./backup.sh -n ~ "/Volumes/Backup Disk/home"
./backup.sh --print-rules ~ /tmp/x

Running the same command again updates an existing backup. Files removed from the source are not deleted from the target.

Symlinks are copied as symlinks, mounted filesystems below the source are not traversed, and a target inside the source is excluded automatically.

Option Description
-n, --dry-run Copy nothing and write the logs for the files that would be copied.
-i, --ignore FILE Use a different ignore list.
-a, --allow FILE Use a different allow list.
--print-rules Print the generated rsync filter rules and exit.
--no-local Leave out the rules in .local/.
-h, --help Show command-line help.

Filters

Both filter files contain one entry per line. Lines beginning with # are comments.

backup.ignore contains paths and patterns that should not be copied:

*.log
node_modules/
/Downloads/

backup.allow lists hidden files and directories that should be copied:

.gitignore
/.zshrc
.git/
/.local/bin/

A nested anchored allow entry such as /.local/bin/ creates a keep-only area: the parent is traversed only far enough to retain the listed subtree. ~/Library uses this mechanism to keep selected data without copying the entire directory.

Local rules

A .local/ folder next to the script may contain its own backup.ignore and backup.allow. Their entries are added to the lists in the repository, so they apply to that machine only. The folder is listed in .gitignore.

As with the repository lists, an ignore entry takes precedence over an allow entry, so a local ignore entry can exclude something the repository allows.

Use --no-local to leave the local rules out. The rules shown by --print-rules include them.

Logs

Each run creates logs/<date>_<time>/.

  • extensions.csv lists file types transferred during the run.
  • progress.log records a file whenever the transferred file type changes, so repeated transitions such as *.txt → *.jpg → *.txt are preserved.
  • files.txt is created during a dry run and lists what rsync would copy.
  • errors.txt is created when rsync reports copy errors.

Use a dry run to review the effective backup before copying data:

./backup.sh -n ~ "/Volumes/Backup Disk/home"

Safety limits

Before copying, the source is scanned once.

Variable Default
MAX_DEPTH 64
MAX_ENTRIES_PER_DIRECTORY 100000
MAX_TOTAL_ENTRIES 5000000
MAX_PREFLIGHT_SECONDS 3600

If a limit is exceeded, the run stops before copying starts. Limits can be overridden for a single run:

MAX_TOTAL_ENTRIES=8000000 ./backup.sh ...

Sensitive data

The allow list includes locations that may contain credentials or other sensitive data, including SSH and GPG keys, .env files, cloud credentials, keychains, and shell history.

Protect the backup destination accordingly.

Tests

tests/run.sh

For the slower traversal test:

tests/run.sh --slow

Contributing

This repository is open to contributions. If you find a bug, an edge case, or a way to improve the robustness or overall quality of the backup script, feel free to open a pull request. Improvements are welcome.

License

See LICENSE.

About

Script to create an extensive backup of macOS

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages