1

I'm trying to use find & rsync to back up specific files from a remote machine, and getting nowhere.

Here's the setup: I want to use rsync to back up all files containing *state* or *srm on the remote machine into a local directory. I specifically want to run this from my local machine, rather than running it with find on the remote machine (a RetroPie, if you're curious), because I don't want to set up login credentials from the remote machine. I already have ssh keys set up properly. I'm aiming to backup into ~/retropie-backup locally.

The find command that I'm using works properly on the remote machine (truncated to one result for clarity):

$ find  -iname "*state*" -o -iname "*srm"
./RetroPie/roms/snes/EarthBound (USA).srm

So far so good. I also know that I need to add -s to rsync so it doesn't panic over spaces in the file names. My attempt at combining the two, however, doesn't work:

$ rsync -v -s pi@retropie:'`find  -iname "*state*" -o -iname "*srm"`' retropie-backup/
rsync: link_stat "/home/pi/`find  -iname "*state*" -o -iname "*srm"`" failed: No such file or directory (2)

I can tell that I'm missing something basic, but I'm just not seeing it. Any suggestions?

2 Answers 2

2

There are a couple of ways of skinning this cat

You can use another ssh invocation to generate the list of files, and pipe that into your rsync. This version requires the GNU extension find -print0 to handle filenames that might contain whitespace, newlines, or other non-printing characters.

ssh -nq pi find -type f \( -iname "*state*" -o -iname "*srm" \) -print0 |
    rsync --dry-run -aiv --from0 --files-from - pi@retropie: retropie-backup/

Another approach is to have rsync directly include only these files. Here you need to include all directories so that rsync will descend into them, include the files of consideration, and then exclude everything else. Finally you need to tell rsync to skip directories that would end up with no content.

rsync --dry-run -aiv --include '*/' --include '*state*' --include '*srm' --exclude '*' --prune-empty-dirs pi@retropie: retropie-backup/

In both cases remove --dry-run to perform the action once you're happy it's selected the correct set of files.

0

The find has to run on the remote machine, which looks like what you are trying to do except your syntax isn't right. Backticks can only run commands on the local machine. You must ssh into the remote machine to run find.

ssh pi@retropie find ... >./filelist
rsync -v -files-from ./filelist pi@retropie: retropie-backup/
3
  • Ah, I see what you mean. So you can't execute any commands remotely with rsync? I must have misunderstood what I was reading.
    – Decoherent
    Commented Dec 28, 2016 at 4:44
  • Aha, a few more minutes of work yielded exactly what I want, piping the file list into rsync. I just didn't know how to search for what I wanted! Thanks for the pointer! ssh pi@retropie find -iname "*state*" -o -iname "*srm" | rsync -v --files-from - pi@retropie:~ retropie-backup/
    – Decoherent
    Commented Dec 28, 2016 at 4:46
  • @Decoherent that won't work if there's one or more file names containing state or ending with srm in the current directory in the local invoking client Commented Jul 9, 2022 at 14:26

You must log in to answer this question.

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