When rsync gets interrupted (either manually with kill or due to system failures), it leaves behind temporary files with extensions like .zxivMN, .XXXXXX or .partial. These files can clutter your target directory and won't be automatically removed by subsequent rsync runs.
First, let's find all these temporary files. They typically follow these patterns:
find /target/directory -type f $-name ".*.??????" -o -name "*.partial"$ -ls
Example output would show files like:
./.document.pdf.zxivMN
./backup.sql.partial
Here are three approaches to clean up these files:
Method 1: Using find with xargs
find /target/directory -type f $-name ".*.??????" -o -name "*.partial"$ -print0 | xargs -0 rm -f
Method 2: Using find -exec
find /target/directory -type f $-name ".*.??????" -o -name "*.partial"$ -exec rm -f {} +
Method 3: Dry Run First
For safety, always do a dry run first:
find /target/directory -type f $-name ".*.??????" -o -name "*.partial"$ -exec echo "Would remove: " {} \;
The best solution is to prevent scattered temp files by specifying a dedicated partial directory:
rsync -ah --partial --partial-dir=.rsync-partials /source/ /target/
Then cleanup becomes simpler:
rm -rf /target/.rsync-partials
For more complex scenarios, consider this bash function:
clean_rsync_temp() {
local target_dir=$1
if [ ! -d "$target_dir" ]; then
echo "Error: Directory doesn't exist" >&2
return 1
fi
echo "Cleaning rsync temp files in $target_dir"
find "$target_dir" -type f $-name ".*.??????" -o -name "*.partial"$ \
-exec sh -c 'echo "Removing $0"; rm -f "$0"' {} \;
# Also clean empty directories if needed
find "$target_dir" -type d -empty -delete
}
When rsync is interrupted (especially with -a or --partial flags), it leaves behind temporary partial files with randomized extensions like .filename.randomchars. These files serve two purposes:
- Allow resuming interrupted transfers
- Ensure atomic file replacement (only when transfer completes successfully)
For immediate cleanup of these artifacts, you can use:
# Basic find command (safe version)
find /target/path -type f -name ".*.*" -size +0 -exec ls -l {} \;
# Aggressive cleanup (verify matches first!)
find /target/path -type f -name ".*.*" -exec rm -v {} \;
Add these rsync options to prevent accumulation:
rsync -ah --remove-source-files --partial-dir=/tmp/rsync-partial src/ dest/
Key parameters:
--partial-dir: Isolates temp files--remove-source-files: Cleans up after verification--delete-after: Post-transfer cleanup
For recurring sync jobs, create a maintenance script:
#!/bin/bash
TARGET="/mnt/archive1/documents"
DAYS_TO_KEEP=1
# Clean orphaned temp files older than N days
find "$TARGET" -type f -name ".*.*" -mtime +$DAYS_TO_KEEP -delete
# Verify cleanup
rsync -ah --dry-run --delete-excluded \
--exclude='.*.*' \
/mnt/archive1/ /mnt/archive2/
Special cases for different storage:
| Filesystem | Recommendation |
|---|---|
| NFS | Use --inplace to reduce rename operations |
| ZFS | Combine with zfs-auto-snapshot for rollback |
| Btrfs | Leverage COW snapshots before major syncs |