A clean, reliable shell script to verify whether files and folders were completely and correctly copied from a source to a destination directory — including subdirectories and hidden files.
Designed for post-copy sanity checking: useful after backups, manual drag-and-drop transfers, SD card dumps, or Android file transfers.
- Recursively compares all files (including hidden ones) between source and destination
- Compares:
- Relative file paths
- File sizes (in bytes)
- (Optionally) file modification timestamps
- Detects:
- Files missing in the destination
- Extra files in the destination
- Files with same path but different size or timestamp (marked as changed)
- Skips:
- macOS AppleDouble files (
._*
) that contain metadata but not actual file content .DS_Store
files — macOS Finder metadata that clutters directories but has no user data
- macOS AppleDouble files (
- Outputs:
- A color-coded summary in terminal
- A detailed diff-style log saved as
verifycopy_diff_output.txt
in the script directory
When copying to non-macOS file systems (e.g. FAT32, exFAT, NTFS, SMB), macOS generates ._*
files — known as AppleDouble files — to store extended metadata like:
- Finder tags and labels
- Custom icons
- Resource forks
These files are not user content, are invisible on macOS, and often confuse verification.
This script excludes them by default, ensuring they don't pollute the results.
Normal dotfiles (like .bashrc
, .config
) are not affected and are fully included.
Timestamps detect changes that file size cannot — for example:
- File was edited but size didn't change
- In real-world edits, file size can remain the same (e.g., a text file is edited but eventually it contains the same number of characters and therefore has the same size), but timestamp can change — enabling timestamp check helps detect such changes reliably without needing checksums.
- File was re-encoded or touched
- File was modified during sync
Timestamp comparison is optional because some copy methods don’t preserve timestamps.
Enable when:
- You used reliable methods that preserve timestamps
- You want to ensure copied files weren’t modified after transfer
Disable when:
- You copied via MTP, browser, or plain
cp
- You want to avoid false positives due to timestamp differences
Recommendation: Enable timestamp checks unless you know your copy tool strips them
Method | Preserves Timestamps |
---|---|
rsync -a , rsync -av |
✅ Yes |
cp -p , cp -a |
✅ Yes |
macOS Finder (drag & drop) | ✅ Yes |
Method / Tool | Preserves Timestamps |
---|---|
cp (without -p ) |
❌ No |
Web/browser downloads | ❌ No |
Android MTP transfer | ❌ No |
Some network (SMB/NFS) shares | ❌ No |
While verifycopy.zsh
is ideal for most real-world usage, it does not perform full content-level validation. Specifically:
- It does not compare actual file contents (no hashing or checksums)
- It does not verify file permissions, symlinks, or extended attributes
- It does not detect bit-level corruption when size and timestamp are identical
If you need full integrity verification, use rsync
with checksums (see next section).
While rsync
is a powerful tool that can detect missing or changed files — and even verify content with checksums — this script exists because:
Feature / Need | verifycopy.zsh ✅ |
rsync (with --dry-run ) |
---|---|---|
Designed purely for post-copy verification | ✅ Yes | ❌ No (sync-focused) |
Fully read-only, always safe | ✅ Yes | --dry-run |
Clear, human-readable summary | ✅ Yes | ❌ No (cryptic output) |
Detects extras in destination | ✅ Yes | ❌ No (requires complex setup) |
Color-coded terminal output | ✅ Yes | ❌ No |
Logs to diff-style file | ✅ Yes | ❌ No |
Skips macOS ._* clutter automatically |
✅ Yes | --exclude='._*' |
Supports timestamp optionality | ✅ Yes | ✅ Yes (--size-only ) |
Supports checksum-based comparison | ❌ No | ✅ Yes (-c ) |
If you need full bit-level verification (e.g. for archives or production systems), use:
rsync -avc --dry-run --exclude='._*' /source/ /destination/
But for day-to-day safety checks after copying files, verifycopy.zsh
is faster, simpler, and safer to use.
git clone https://github.com/agarwalvishal/verifycopy.git ~/Tools/verifycopy
cd ~/Tools/verifycopy
chmod +x verifycopy.zsh
ln -s ~/Tools/verifycopy/verifycopy.zsh /usr/local/bin/verifycopy
You can now run:
verifycopy
Run the script:
verifycopy
Then:
- Enter the source folder path
- Enter the destination folder path
- Choose whether to compare timestamps
After scanning and comparing, a diff log is saved as:
~/Tools/verifycopy/verifycopy_diff_output.txt
To remove the command:
rm /usr/local/bin/verifycopy
To delete the script and diff output:
rm -rf ~/Tools/verifycopy
verifycopy.zsh
is a focused tool that answers a simple but critical question:
"Did all my files copy correctly?"
- It verifies the success of manual file copies and provides peace of mind before deleting original files and helps catch skips, overwrites, or modifications.
- It’s designed to give you fast, trustworthy feedback — without needing to understand
rsync
, parse obscure flags, or risk overwriting data. - Use it confidently for backups, file migrations, or post-transfer validation when bit-level hashing is overkill.
This script is backed by an automated test suite covering all meaningful file copy edge cases — including missing files, size mismatches, timestamp-only differences, and known safe exclusions.