1

I'm trying to transfer files which have been updated in the 31 days. I'm trying to run

/bin/rsync --remove-source-files --files-from="<(find /tmp/rsync/source -type f -mtime -31 -print0)" /tmp/rsync/source /tmp/rsync/destination

However when trying this, i keep receiving the following error:

failed to open files-from file <(find /tmp/rsync/source -type f -mtime -31 -print0): No such file or directory

The directory exists and is accessible.

This is the output of the find:

$ find /tmp/rsync/source -type f -mtime -31  
/tmp/rsync/source/testfile2.txt  
/tmp/rsync/source/testfile.txt  
/tmp/rsync/source/sourcefile.txt
Jeroen Claes
  • 27
  • 1
  • 5

4 Answers4

0

It's unfortunate this this is coming up first in search results when other questions about this have much better answers.

I've seen people use the --files-from="<(...)" notation several places, but I don't see any reference to it in the rsync manual. Maybe it's a special shell syntax for some people? or distro-added feature? I get the same error message as above when I try to use that notation.

The official way to do it is to either write your list of files into a real file:

find . -mtime -7 > past_week.txt
rsync --files-from=past_week.txt SRC/ DST/

or to pipe the list of files on stdin:

find . -mtime -7 | rsync --files-from=- SRC/ DST/

The single dash - filename here means STDIN, and this is a common convention among unix tools.

If you are worried about files with newlines in the file name, you should use NUL delimiters for the list. (but beware this will also affect --include-from and --exclude-from)

find . -mtime -7 -print0 | rsync -0 --files-from=- SRC/ DST/

You can also list out the files on the command line like rsync -av `find . -mtime -7` DST/ but that doesn't preserve their hierarchy in the tree, and if you have more than a few files that will create a massive command line, and may fail to execute if it exceeds the limit of the operating system.

dataless
  • 388
  • 4
  • 9
  • --from-files is not an option (`rsync: --from-files=/tmp/include3.txt: unknown option'). Not sure whether you meant `--include-from` or something else). – ywarnier Sep 04 '22 at 09:52
  • 1
    @ywarnier Sorry, dyslexia on display there. The options is ``--files-from``. I updated the answer. – dataless Sep 14 '22 at 18:54
0

/bin/rsync --remove-source-files --files-from="<(find /tmp/rsync/source -type f -mtime -31 -print0)" /tmp/rsync/source /tmp/rsync/destination

<( ... ) is Bash Shell Process Substitution - https://www.gnu.org/software/bash/manual/html_node/Process-Substitution.html.

So:

  1. You have to be using Bash, i.e. as your command-line shell if running interactively, or as the shell script interpreter, if running in a shell script.
  2. If not using Bash on command-line nor in a shell script or if you are passing that command to something that is executing the rsync program directly and not through a Bash shell, it won't work.
  3. You can't put that syntax inside double quotes as shown. When quoted like that, Bash interprets it as a filename (thus the error).
Bert F
  • 85,407
  • 12
  • 106
  • 123
-2

Tried, this works good for me

find /tmp/rsync/source -type f -mtime -31 | rsync -rcvh /tmp/rsync/source/ /tmp/rsync/destination/ --dry-run

Remove dry-run for actual execution

San
  • 226
  • 5
  • 14
-2

Since i was forced to use a pre-existing script which was parsing on "{" brackets and where you couldn't run commands before the rsync script i was unable to use the above mentioned solutions.

However i was able to use the following to get it working:

/bin/rsync --recursive --remove-source-files `find /tmp/rsync/source -type f -mtime -31` /tmp/rsync/destination
Jeroen Claes
  • 27
  • 1
  • 5