7

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.

2
  • isn't there a colon ':' missing from the source? Nov 8, 2015 at 1:57
  • 1
    if you want the remote path to be relative to the remote user's home directory, leave out the slash after the colon. Nov 8, 2015 at 12:33

4 Answers 4

5

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.

1

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 .
2
  • Don't forget the colon after the hostname.
    – Jim L.
    Dec 15, 2021 at 21:51
  • @JimL. right on
    – cmc
    Dec 15, 2021 at 22:43
1

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.

4
  • 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.
    – RobertL
    Nov 7, 2015 at 0:32
  • @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.
    – David King
    Nov 8, 2015 at 1:07
  • 1
    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!
    – RobertL
    Nov 8, 2015 at 1:16
  • @RobertL That's a good point. So edited.
    – David King
    Nov 8, 2015 at 1:20
0

The way to get the information by return code would be to write a shell script that calls rsync and execute the shell script from java. There are some major problems with this as I outline below. The shell script could look like this:

#!/bin/sh
if OUTPUT=$(rsync -a --info=NAME --update user@remotehost/files/ ~/files/)
then
    if [ "$OUTPUT" != "" ]                   # got output?
    then
        exit 0  # yes, success, "some" files were updated
    fi
fi
exit 1  # either rsync failed or no files were updated

The main problem with this is that you won't be able to tell if the synchronization process itself completed successfully. You only know if files were updated or not. That's why I'd recommend collecting the output in java and count the lines and check the return code in java.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .