When transferring files from a remote server using rsync, sometimes you need a one-way synchronization that only copies non-existent files to the local machine, without updating existing files even if the remote version is newer. This differs from rsync's default behavior which typically updates changed files.
To achieve this specific behavior, you'll need these key flags:
rsync -avz --ignore-existing --progress user@remote:/path/to/source/ /local/destination/
Flag breakdown:
- -a: Archive mode (preserves permissions, ownership, timestamps)
- -v: Verbose output
- -z: Compression during transfer
- --ignore-existing: Skip files that already exist on receiver
- --progress: Show transfer progress (optional)
For cron automation, we need SSH key-based authentication:
ssh-keygen -t rsa -b 4096
ssh-copy-id user@remote-server
Here's a robust script you can use in cron jobs:
#!/bin/bash
REMOTE_USER="your_username"
REMOTE_HOST="remote.server.com"
SOURCE_PATH="/remote/source/path/"
DEST_PATH="/local/destination/path/"
LOG_FILE="/var/log/rsync_new_files.log"
{
echo "=== Starting rsync: $(date) ==="
rsync -avz --ignore-existing --progress ${REMOTE_USER}@${REMOTE_HOST}:${SOURCE_PATH} ${DEST_PATH}
echo "=== Completed: $(date) ==="
} >> ${LOG_FILE} 2>&1
Add this to your crontab (run crontab -e
):
0 3 * * * /path/to/your/rsync_script.sh
This runs the script daily at 3 AM. Adjust the schedule as needed.
Consider these additional scenarios:
# Exclude specific file patterns
rsync -avz --ignore-existing --exclude='*.tmp' --exclude='*.log' user@remote:/source/ /dest/
# Dry run first to verify
rsync -avzn --ignore-existing user@remote:/source/ /dest/
# Limit bandwidth (1000 KB/s)
rsync -avz --ignore-existing --bwlimit=1000 user@remote:/source/ /dest/
When automating file transfers between servers, I frequently encounter scenarios where I need to:
- Pull files from a remote server without any risk of pushing local changes back
- Copy only files that don't exist locally, ignoring newer remote versions
- Run the operation automatically via cron without password prompts
After testing various combinations, this rsync command meets all requirements:
rsync -avz --ignore-existing --progress --dry-run user@remote:/path/to/source/ /local/destination/
Key flags breakdown:
-a
: Archive mode (preserves permissions, timestamps)-v
: Verbose output-z
: Compression during transfer--ignore-existing
: Skips files that already exist locally--progress
: Shows transfer progress--dry-run
: Simulation mode (remove for actual operation)
For cron automation, configure SSH key authentication:
ssh-keygen -t rsa -b 4096
ssh-copy-id user@remote.server
Test connection works without password:
ssh user@remote.server
Create a bash script (~/scripts/rsync_pull.sh
):
#!/bin/bash
LOG_FILE="/var/log/rsync_pull.log"
echo "Starting sync: $(date)" >> $LOG_FILE
rsync -avz --ignore-existing user@remote:/source/path/ /local/path/ >> $LOG_FILE 2>&1
echo "Sync completed: $(date)" >> $LOG_FILE
Make it executable:
chmod +x ~/scripts/rsync_pull.sh
Add to crontab (crontab -e
):
0 3 * * * /home/user/scripts/rsync_pull.sh
For syncing web assets without overwriting local modifications:
rsync -avz --ignore-existing --exclude='*.tmp' --exclude='cache/' \
webuser@prod-server:/var/www/assets/ /home/dev/assets_backup/
- Test with
--dry-run
first - Check
/var/log/cron
for cron errors - Verify SSH key permissions (600 for private key)
- Consider
--bwlimit=RATE
for large transfers