When using rsync for deployment between staging and production environments, the default output can be overwhelmingly verbose. Using the command:
rsync -rzai --progress --stats --ignore-times --checksum /tmp/app_export/ root@app.com:/var/www/html/app/
We get output showing every file comparison, not just the modified files being transferred. This makes it difficult to quickly verify which files will actually change during deployment.
While grep fcst
works as a basic filter, we can do better with rsync's built-in capabilities. The -i
(--itemize-changes) flag actually provides all the information we need - we just need to interpret its output format.
Each line in the output represents:
YXcstpoguax path/to/file
Where the first 11 characters are flags indicating what changed. The key flags we care about are:
f
- file is being transferredc
- checksum differs (file changed)
Combine the itemized output with grep to show only changed files:
rsync -rzai --dry-run --ignore-times --checksum /tmp/app_export/ root@app.com:/var/www/html/app/ | grep '^[^.]*c'
This regex matches lines where 'c' appears in the flags (indicating checksum difference) while ignoring other changes like permissions.
For a PHP deployment scenario, you might want to:
- See only changed PHP files:
rsync -rzai --dry-run --ignore-times --checksum /tmp/app_export/ root@app.com:/var/www/html/app/ \ | grep -E '^[^.]*c.*\.php$'
- Get machine-readable output for logging:
rsync -rzai --dry-run --ignore-times --checksum /tmp/app_export/ root@app.com:/var/www/html/app/ \ | awk '/^[^.]*c/ {print $2}'
- The
--checksum
flag is crucial - it forces content comparison --ignore-times
ensures we don't skip files with identical timestamps- For very large transfers, consider adding
--progress
to monitor status
--out-format /h2>
For more control over output formatting in newer rsync versions (3.1.0+):
rsync -rzai --dry-run --ignore-times --checksum \
--out-format='%i %n' /tmp/app_export/ root@app.com:/var/www/html/app/ \
| grep '^c'
This gives cleaner output showing just changed files with their paths.
When running rsync for deployment between environments, we often face information overload. The standard output shows all files being compared, not just those actually being transferred. Here's what a typical deployment command might look like:
rsync -rzai --progress --stats --ignore-times --checksum /tmp/app_export/ root@app.com:/var/www/html/app/
The -i
(itemize changes) flag is what generates the detailed output, but it shows everything. Each line begins with a status indicator:
fcst
- File is being transferred (changed content).f...
- File exists and is unchangedcd++++
- Directory being created
Here are three effective ways to filter only modified files:
Method 1: Grep filtering
rsync -rzai --dry-run /source/ user@dest:/target/ | grep '^[^.]'
Method 2: Using --out-format (rsync 3.1.0+)
rsync -razi --out-format='%i %n' --dry-run /source/ user@dest:/target/ | awk '/^[^.]/ {print $2}'
Method 3: JSON output with jq (advanced parsing)
rsync -rai --dry-run --info=json /source/ user@dest:/target/ | jq -r 'select(.transfer_size > 0) | .path'
For PHP deployment scenarios, you might want to capture the changed files list into a variable:
changed_files=$(rsync -rzai --dry-run /tmp/app_export/ root@app.com:/var/www/html/app/ | grep '^[^.]' | awk '{print $2}')
echo "Files to be updated:"
echo "$changed_files"
Always combine with --dry-run
for pre-deployment checks:
if rsync -rzai --dry-run /tmp/app_export/ root@app.com:/var/www/html/app/ | grep -q '^[^.]'; then
echo "Changes detected, proceeding with deployment..."
rsync -rzai /tmp/app_export/ root@app.com:/var/www/html/app/
else
echo "No changes detected, skipping deployment."
fi
Remember that --checksum
adds significant overhead as it verifies file contents. For large deployments, consider these alternatives:
- Use
--size-only
for faster (but less accurate) comparisons - Implement incremental deployment strategies
- Combine with versioned deployments when possible