2

I have been copying some files and folders by building an rsync command manually using a string list in the shell.

For remote file structure like:

/home/foo/
  media/
    bigfile.bin
  somedir/
    a.txt
    b.json

I would write:

rsync -Pavz my_remote:/home/foo/{media/bigfile.bin,somedir} .

The resulting local file structure is

./bigfile.bin
./somedir/
  a.txt
  b.json

The directory structure is important. bigfile.bin is not locally in a media/ dir but somedir was copied recursively. This is what I want.

Now, I have a script to build a list of files to be transferred so I can use

rsync -Pavz --files-from=list.txt my_remote:/home/foo

where list.txt is

media/bigfile.bin
somedir/

Now, the resulting local file structure is

./media/
  bigfile.bin
./somedir/
  a.txt
  b.json

I now have the media directory that I don't want, I guess because of the common base directory as my_remote:/home/foo. Is there any way to recover the previous behavior while using --files-from? If I turn on --no-R, that flattens everything, but actually I still want somedir/. More generally, the desired behavior is "take the base part of the specified path (bigfile.bin, somedir) and copy it & its contents contents recursively, ignoring parent directories (media) in destination paths."

I could also use a script to build the rsync command with curly braces to be expanded by the shell as I was doing initially, but I potentially have to deal with a headache of character escapes in remote filenames that I'd rather avoid by using --files-from.

1 Answer 1

3

I think what you are looking for is the following (rsync versions => 2.6.7).

In your list.txt add a dot slash ./ at the end of the path you don't want to be included:

media/./bigfile.bin
somedir/

In this case ./ makes rsync ignore the path media/ of the line media/./bigfile.bin.

From the man page

--relative, -R
        ...

        It  is  also  possible  to limit the amount of path information that is
        sent as implied directories for each path you specify.  With  a  modern
        rsync  on the sending side (beginning with 2.6.7), you can insert a dot
        and a slash into the source path, like this:

            rsync -avR /foo/./bar/baz.c remote:/tmp/

I've just tested and it seems to work as I understand you intend.

0

You must log in to answer this question.

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