Get rsync to report if any local files were updated

5,306

Solution 1

You cannot get rsync to tell you that via the exit code. The exit codes have documented predefined meanings.

I think the best way to do this from java would be to add the option --info=NAME to mention only updated directory and file names:

rsync -a --info=NAME --update user@remotehost/files/ ~/files/

This prints the names of updated files and directories, one per line, on standard output (fd = 0).

Then you would collect the output from rsync and count the number of newlines in the string.

I think a good way to collect the output in java can be found in this answer, but I haven't tried it: https://stackoverflow.com/a/9048519/5484716

Do not use redirectErrorStream or in any other way merge the standard output an standard error streams. If you do, you will count error messages as updated files, not what you want.

Solution 2

The --info flag on rsync will output the path of any file transferred. The exit code of rsync indicates success/failure so you wouldn't be able to use it without wrapping a script around the command like

#!/bin/bash

files=$(rsync -a --info=NAME --update user@remotehost/files/ ~/files/)

if [ $files = "" ]; then
  # files weren't transferred
  exit 0
else
  # files were transferred
  exit 1
fi

and then calling that script from java instead of the rsync command directly. rsync will probably output some other lines of text at the beginning and end of the transmission so you may need to adjust the if statement to account for the extra lines of output but the basic idea would work.

Solution 3

Based on @DavidKing's idea to let rsync print copied file names, and expanded with information from @yashma that grep will exit nonzero exit status when stdin was empty, we can come up with this satisfyingly short and cryptic one-liner:

# prints file list, exits nonzero when that list is empty
rsync -a --info=NAME --update user@remotehost:/files/ ~/files/ | grep .
Share:
5,306

Related videos on Youtube

Fidel
Author by

Fidel

Updated on September 18, 2022

Comments

  • Fidel
    Fidel almost 2 years

    I'm running rsync to do pull from a remote host to the local host.

    rsync -a --update user@remotehost:/files/ ~/files/
    

    I'm running that command from java and using the exit code to work out if it was successful or not.

    Is it possible to get that command to report back if any local files were modified? Reporting back via an exit code would be ideal.

    • benishky
      benishky over 8 years
      isn't there a colon ':' missing from the source?
    • benishky
      benishky over 8 years
      if you want the remote path to be relative to the remote user's home directory, leave out the slash after the colon.
  • RobertL
    RobertL over 8 years
    David, exit 1 tells the caller that the command failed. exit 0 tells the caller that the command succeeded. This script always calls exit 1 because rsync -av always prints output, whether files were transferred or not.
  • David King
    David King over 8 years
    @RobertL note my comment about adjusting the if statement to account for the extra lines of output. I realize that there will be lines printed even if no files were transferred but the number of lines is depending on version, distro, etc. so I left it up to whoever is actually implementing it to get the number right.
  • RobertL
    RobertL over 8 years
    That's cool. I get it. I was just pointing out that the script, as written, is not functional. Replace the v with ` --info=NAME` and the script works as expected without needing to adjust the if statement or otherwise post-process the output of rsync. Thanks for responding!
  • David King
    David King over 8 years
    @RobertL That's a good point. So edited.
  • Jim L.
    Jim L. over 2 years
    Don't forget the colon after the hostname.
  • cmc
    cmc over 2 years
    @JimL. right on