rsync -n (--dry-run): preview what rsync would copy or delete
- tool
- rsync
- versions
- rsync 3.x
- os
- linux, macos
rsync -avn src/ dest/ (or --dry-run) runs the whole comparison but changes nothing: it prints the files it would transfer and, with --delete, the files it would delete. Add -i (--itemize-changes) to see why each file is listed. Run every new rsync command, and every command with --delete, as a dry run first; when the list looks right, run the same command without -n.
Commands
# Preview a sync, with a reason code for each file
rsync -avni ./site/ /var/www/site/
# Preview deletions of a mirror
rsync -avn --delete ./site/ user@server.example.com:/var/www/site/
# Same, as a list of what would be removed only
rsync -avn --delete ./site/ /var/www/site/ | grep '^deleting '
# Real run once the preview is right
rsync -av --delete ./site/ /var/www/site/The output of -i is meant to be exactly the same in the dry run and in the following real run, unless the files change in between, so the preview can be trusted.
Reading the itemized output
Each line starts with an 11-character code such as >f+++++++++ index.html or .d..t...... assets/:
| Position | Values |
|---|---|
| 1: update type | < sent to the remote, > received, c local change or creation, h hard link, . not updated, * message (for example *deleting) |
| 2: file type | f file, d directory, L symlink, D device, S special file |
| 3-11: attributes | c checksum, s size, t time, p permissions, o owner, g group, u/n/b access/create times, a ACL, x extended attributes |
| + in every attribute | The item is new |
| . in an attribute | That attribute is unchanged |
| Example | Meaning |
|---|---|
| >f+++++++++ docs/new.md | New file, will be transferred |
| >f.st...... app.js | Size and time differ, the file will be updated |
| .f...p..... run.sh | Only the permissions will change, no data is sent |
| cd+++++++++ img/ | A new directory will be created |
| *deleting old.css | Will be deleted (with --delete); the code column reads *deleting |
Options to combine with -n
| Option | Why |
|---|---|
| -v | List each file name |
| -i, --itemize-changes | Show what changes for each file; -ii also lists unchanged files |
| --delete | Include the deletions in the preview |
| --stats | Totals: number of files, files to transfer, total size |
| --out-format="%i %n%L" | The format -i uses; customise it for scripts |
| --max-delete=0 | Without -n: warn about extra files on the receiver but delete none |
Pitfalls
- Forgetting
-non the real command line. Keep the dry run and real command identical except for-n, for example by editing the previous history line, so the preview matches what runs. - Trailing slash changes the target.
rsync -an src destandrsync -an src/ destpreview different layouts. Read the paths in the output; the first form createsdest/src/. - Empty output does not mean failure. If nothing differs,
-nprints only the summary lines; the exit status is 0 as for a real run. - Availability. rsync runs on Linux and macOS (recent macOS releases ship
openrsync, which supports-nbut not every rsync option); on Windows use WSL or Cygwin.
Exit codes are the same as for a real run: 0 on success, 23 for partial transfer errors and so on (see rsync exit codes).
FAQ
Does a dry run connect to the remote host?
Yes. rsync still logs in over ssh and compares the file lists on both sides; it only skips sending data and changing anything. A dry run therefore needs the same access as the real run and catches login and path errors too.
Why does the dry run show the same files every time?
Usually because times or permissions cannot be preserved on the destination, for example on a FAT or SMB filesystem, so rsync sees a difference on every run. Look at the itemize letters: t or p in every line points at that. --modify-window=1 helps with FAT timestamps.
Are the statistics of a dry run accurate?
The list of changes is, but the byte counts are not: a dry run sends no file data, so bytes sent, literal data and speedup are smaller than in a real run, and --progress shows nothing.