关于scp:rsync – 创建所有缺少的父目录?

rsync - create all missing parent directories?

我正在寻找一个类似于rsync的程序,它将在远程端创建任何丢失的父目录。

例如,如果我在一台服务器上有/top/a/b/c/d,而远程服务器上只有/top/a,我想将d复制到远程服务器,并创建bc目录。

命令:

1
rsync /top/a/b/c/d remote:/top/a/b/c

无法工作,因为远程服务器上不存在/tmp/a/b。如果它确实存在,那么文件d将被复制到路径/top/a/b/c

这可能与使用--include--exclude开关的rsync有关,但它非常复杂,例如:

1
2
3
4
5
6
7
8
9
rsync -v -r a dest:dir  \
  --include 'a/b'       \
  --include 'a/b/c'     \
  --include 'a/b/c/d'   \
  --include 'a/b/c/d/e' \
  --exclude 'a/*'       \
  --exclude 'a/b/*'     \
  --exclude 'a/b/c/*'   \
  --exclude 'a/b/c/d/*'

即使中间目录有文件,也只会将a/b/c/d/e复制到dest:dir/a/b/c/d/e中。(注意-include必须在excludes之前。)

还有其他选择吗?


你可能在找

1
rsync -aR

例如:

1
rsync -a --relative /top/a/b/c/d remote:/

在其他问题中也可以看到这个技巧。


1
rsync -aq --rsync-path='mkdir -p /tmp/imaginary/ && rsync' file user@remote:/tmp/imaginary/

从http://www.schwertly.com/2013/07/forcing-rsync-to-create-a-remote-path-using-rsync-path/,但是不要从那里复制和粘贴,他的语法被删去了。

它允许您执行任意命令来设置rsync可执行文件的路径。


我建议您手动执行存在:

1
2
ssh user@remote mkdir -p /top/a/b/c
rsync /top/a/b/c/d remote:/top/a/b/c

如果目标文件夹不存在,则创建该文件夹。


根据https://unix.stackexchange.com/a/496181/5783,自rsync 2.6.7以来,如果使用.锚定要在目标位置创建的起始父目录,--relative工作:

1
2
3
4
5
6
7
8
9
10
derek@DESKTOP-2F2F59O:~/projects/rsync$ mkdir --parents top1/a/b/c/d
derek@DESKTOP-2F2F59O:~/projects/rsync$ mkdir --parents top2/a
derek@DESKTOP-2F2F59O:~/projects/rsync$ rsync --recursive --relative --verbose top1/a/./b/c/d top2/a/
sending incremental file list
b/
b/c/
b/c/d/

sent 99 bytes  received 28 bytes  254.00 bytes/sec
total size is 0  speedup is 0.00


我在寻找一个更好的解决方案,但我的似乎更适合当你有太多的子目录来手动创建它们。

只需使用cp作为--parents选项的中间步骤

1
2
cp --parents /your/path/sub/dir/ /tmp/localcopy
rsync [options] /tmp/localcopy/* remote:/destination/path/

cp --parents将为您创建结构。

如果只想复制父文件夹的一个子集,可以从任何子文件夹调用它。


因为我有不同的设置,所以--relative不适合我。也许我只是不明白--relative是如何工作的,但我发现

1
2
ssh remote mkdir -p /top/a/b/c
rsync /top/a/b/c/d remote:/top/a/b/c

很容易理解并完成工作。