Copy, sync and archive: cp, rsync and tar done right
Copy and sync folders without surprises, pack archives with tar, and know what a real backup needs.
Part 12 of 12 in Linux basics for self-hosters. Last updated
In short: rsync -a src/ dest/ copies the contents of src into dest and keeps permissions and timestamps; without the trailing slash on src you get dest/src instead. Add --delete to make dest an exact mirror, but run it with -n (dry run) first. tar -caf backup.tar.zst folder packs a folder into a compressed archive and tar -xf backup.tar.zst unpacks it. A mirror copies your mistakes too, so real backups need versions: restic or borg.
cp: quick local copies
cp notes.txt notes.bak # one file
cp -a ~/photos /mnt/usb/ # a directory, keeping permissions, owners and times
cp -i big.iso /mnt/usb/ # ask before overwriting
cp --update=none big.iso /mnt/usb/ # never overwrite an existing file cp -r copies recursively but resets owners and timestamps; cp -a keeps
them and is almost always what you want. cp is fine for one-off copies on the same machine.
For anything large, repeated or over the network, use rsync: it can resume, and it only
transfers what changed.
rsync and the trailing slash
One character decides where your files land: a slash at the end of the source means "the contents of this directory".
rsync -a photos/ /mnt/backup/photos/ # result: /mnt/backup/photos/IMG_0001.jpg
rsync -a photos /mnt/backup/photos/ # result: /mnt/backup/photos/photos/IMG_0001.jpg Both forms side by side, run in an empty scratch directory:
$ rsync -a photos backup-a; rsync -a photos/ backup-b; find backup-a backup-b | sort
backup-a
backup-a/photos
backup-a/photos/2026
backup-a/photos/2026/beach.jpg
backup-a/photos/2026/tent.jpg
backup-a/photos/index.txt
backup-b
backup-b/2026
backup-b/2026/beach.jpg
backup-b/2026/tent.jpg
backup-b/index.txt Real output on openSUSE Tumbleweed, 2026-09-28; user and host names and addresses redacted.
The flags you will use again and again:
rsync -avh --info=progress2 src/ dest/ # verbose file list, overall progress
rsync -avn --delete src/ dest/ # DRY RUN: what would be copied and deleted
rsync -a --delete src/ dest/ # make dest an exact mirror of src
rsync -a --exclude '*.tmp' --exclude 'cache/' src/ dest/
sudo rsync -aHAX --numeric-ids /srv/data/ /mnt/backup/data/ # system data: links, ACLs, xattrs, raw IDs -n (--dry-run) lists every change without making it. Lines starting
with deleting are files that will disappear from the destination. Always read that
list before the first real --delete run. The man page is long but worth a search:
rsync(1).
A dry run against the mirror from above: first nothing to do, then after adding one file and removing another from the source:
$ rsync -av --delete --dry-run photos/ backup-b/
sending incremental file list
sent 143 bytes received 13 bytes 312.00 bytes/sec
total size is 9 speedup is 0.06 (DRY RUN)
$ touch photos/2026/new.jpg; rm photos/index.txt
$ rsync -av --delete --dry-run photos/ backup-b/
sending incremental file list
deleting index.txt
2026/new.jpg
sent 142 bytes received 29 bytes 342.00 bytes/sec
total size is 4 speedup is 0.02 (DRY RUN) Real output on openSUSE Tumbleweed, 2026-09-28; user and host names and addresses redacted.
rsync over SSH
rsync talks SSH by default when either side has a host: prefix. It needs rsync
installed on both ends.
rsync -avz ~/photos/ alice@192.168.1.60:/srv/backup/photos/ # push
rsync -avz alice@192.168.1.60:/srv/backup/photos/ ~/restore/ # pull
rsync -avz -e 'ssh -p 2222 -i ~/.ssh/id_ed25519' ~/photos/ alice@192.168.1.60:/srv/backup/photos/
rsync -avz ~/photos/ nas:/srv/backup/photos/ # with a "Host nas" entry in ~/.ssh/config -z compresses on the wire, which helps over slow links and costs CPU on a fast LAN;
skip it for photos and video, which are compressed already. For unattended jobs, use an
ed25519 key and a ~/.ssh/config entry so the command stays short. The
SSH key and config helper walks you through
both.
tar: archives with gzip or zstd
tar -czf etc.tar.gz /etc # create, gzip
tar -caf etc.tar.zst /etc # create, compression from the extension (zstd)
tar --zstd -cf etc.tar.zst /etc # the same, zstd named explicitly
tar -tf etc.tar.zst # list the contents
tar -tvf etc.tar.zst # list with permissions, owners and dates
tar -xf etc.tar.zst # extract here
tar -xf etc.tar.zst -C /tmp/restore # extract into another directory
tar -xf etc.tar.zst etc/fstab # extract one file
tar -czf app.tar.gz --exclude='*.log' app/ # leave files out
Read the letters as words: create, extract,
list, f for the archive file (always last, directly before its
name), z for gzip, a for "pick compression from the name".
zstd is faster than gzip at a similar or better ratio. tar strips the leading /,
so an archive of /etc extracts as etc/ in the current directory and
never over your real /etc. Run it with sudo to read every file and keep owners.
Reference: the GNU tar manual.
Create, list and restore the same folder with zstd:
$ tar --zstd -cf photos.tar.zst photos; tar --zstd -tvf photos.tar.zst
drwxr-xr-x user/user 0 2026-09-28 06:36 photos/
drwxr-xr-x user/user 0 2026-09-28 06:36 photos/2026/
-rw-r--r-- user/user 2 2026-09-28 06:36 photos/2026/beach.jpg
-rw-r--r-- user/user 2 2026-09-28 06:36 photos/2026/tent.jpg
-rw-r--r-- user/user 0 2026-09-28 06:36 photos/2026/new.jpg
$ mkdir restore && tar --zstd -xf photos.tar.zst -C restore && find restore -type f | sort
restore/photos/2026/beach.jpg
restore/photos/2026/new.jpg
restore/photos/2026/tent.jpg Real output on openSUSE Tumbleweed, 2026-09-28; user and host names and addresses redacted.
Why a copy is not a backup
A mirror is only as good as the last run. Delete a folder by accident, or let ransomware encrypt
it, and the next rsync --delete faithfully mirrors the damage. A backup needs three
things a plain copy lacks:
- Versions: yesterday's, last week's and last month's state, not just the latest.
- A second place: a disk in the same machine dies in the same fire, flood or power surge.
- A tested restore: a backup you have never restored from is a hope, not a backup.
restic and borg keep deduplicated, encrypted snapshots, so a hundred versions cost little more than one:
restic -r /mnt/backup/restic init # once: create the repository
restic -r /mnt/backup/restic backup ~/photos # every run: a new snapshot
restic -r /mnt/backup/restic snapshots # list them
restic -r /mnt/backup/restic restore latest --target /tmp/restore The rsync and tar backup command builder writes the script, the dry run, a nightly systemd timer and the restore command for you. For your own schedule, the cron schedule builder gives the timer line, and the directory layout guide lists what is worth backing up.
Common mistakes
rsync --delete with the source and destination swapped
rsync -a --delete /mnt/backup/photos/ ~/photos/ makes your photo folder match the
(older) backup and deletes every newer picture. Source first, destination second, and a
-n dry run before any --delete.
Backing up to an unmounted mount point
If the USB disk or NAS share is not mounted, /mnt/backup is an empty folder on
your system disk, and rsync fills it until the disk is full. Start scripts with
mountpoint -q /mnt/backup || exit 1.
tar -cvf with the f in the wrong place
f takes the next word as the archive name. tar -cfv backup.tar dir
writes an archive called v and tries to add a file called
backup.tar. Keep f last: tar -cvf backup.tar dir.
Frequently asked questions
What does the trailing slash mean in rsync?
A slash at the end of the source means 'the contents of this directory': rsync -a photos/ /mnt/backup/photos/ puts the files directly in /mnt/backup/photos. Without it, rsync -a photos /mnt/backup/photos/ creates /mnt/backup/photos/photos. The slash on the destination makes no difference.
How do I extract a tar.gz or tar.zst file?
tar -xf file.tar.gz or tar -xf file.tar.zst; GNU tar recognises the compression by itself. Add -C /target/dir to extract somewhere else, and look inside first with tar -tf file.tar.zst.
Is rsync a backup?
rsync makes a copy. If a file is deleted, damaged or encrypted by ransomware, the next rsync run copies that state over the good version, especially with --delete. A backup keeps several versions over time; restic and borg do that efficiently and encrypt the data.
What does rsync -a do?
-a (archive) is short for -rlptgoD: recursive, keep symbolic links, permissions, modification times, group, owner (when run as root) and device files. It is the right default for copying directories. Add -H, -A and -X for hard links, ACLs and extended attributes.