rsync:如何排除多种文件类型?

rsync:如何排除多种文件类型?

这是运行 Catalina 的 Mac 上的 bash:

这有效:

rsync -Pa --rsh="ssh -p 19991" --exclude '*.jpg' --exclude '*.mp4' pi@localhost:/home/pi/webcam /Volumes/Media/Webcam\ Backups/raspcondo/webcam/

这些不:

rsync -Pa --rsh="ssh -p 19991" --exclude={'*.jpg', '*.mp4'} pi@localhost:/home/pi/webcam /Volumes/Media/Webcam\ Backups/raspcondo/webcam/

rsync -Pa --rsh="ssh -p 19991" --exclude {'*.jpg', '*.mp4'} pi@localhost:/home/pi/webcam /Volumes/Media/Webcam\ Backups/raspcondo/webcam/

这是输出:

building file list ...
rsync: link_stat "/Users/mnewman/*.mp4}" failed: No such file or directory (2)
rsync: link_stat "/Users/mnewman/pi@localhost:/home/pi/webcam" failed: No such file or directory (2)
0 files to consider
sent 29 bytes  received 20 bytes  98.00 bytes/sec
total size is 0  speedup is 0.00
rsync error: some files could not be transferred (code 23) at /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-54.120.1/rsync/main.c(996) [sender=2.6.9]

我对要排除的文件类型列表做错了什么?

答案1

首先,你的第一个例子是有效的——使用它有什么问题吗?

如果您确实不想这样做,请尝试--exclude=*.{jpg,mp4},它将(在某些 shell 中)扩展为--exclude=*.jpg --exclude=*.mp4,但请注意:

  1. 这是一个外壳特征被称为支撑扩张。这是不是rsync 或 rsync 过滤规则的一个功能。

    如果您错误地认为 rsync 将使用大括号本身(它不会,也不能,甚至永远不会看到大括号),这很容易导致混乱和“令人惊讶”的行为。

  2. 扩展完成rsync 被执行。 rsync 只能看到,例如, --exclude=*.mp4 因为当前目录中没有与该模式匹配的文件名。

  3. 万一有任何文件名匹配--exclude=*.mp4--exclude=*.jpg,大括号扩展将扩展到那些确切的文件名,而不带通配符。

例如

$ mkdir /tmp/test
$ cd /tmp/test
$ echo rsync --exclude=*.{jpg,mp4}
rsync --exclude=*.jpg --exclude=*.mp4

到目前为止,一切都很好...但是看看当文件名与大括号扩展实际匹配时会发生什么:

$ touch -- --exclude=foo.jpg
$ touch -- --exclude=bar.mp4
$ touch -- --exclude=foobar.mp4
$ echo rsync --exclude=*.{jpg,mp4}
rsync --exclude=foo.jpg --exclude=bar.mp4 --exclude=foobar.mp4

避免输入大量--exclude选项的更好方法是使用数组和 printf:

excludes=('*.mp4' '*.jpg')
rsync ...args... $([ "${#excludes[@]}" -gt 0 ] && printf -- "--exclude='%s' " "${excludes[@]}") ...more args...

这将产生如下命令行:

rsync ...args... --exclude='*.mp4' --exclude='*.jpg'  ...more args...

更好的是使用数组和进程替换来为--exclude-from.例如

rsync ... --exclude-from=<([ "${#excludes[@]}" -gt 0 ] && printf -- '- %s\n' "${excludes[@]}") ... 

答案2

--exclude={'*.jpg', '*.mp4'}不做大括号扩展因为左大括号和右大括号是分开的。大括号扩展从具有可变部分的单个单词构建多个单词。删除空间。

rsync … --exclude={'*.jpg','*.mp4'} …

或者

rsync … --exclude='*.'{jpg,mp4} …

after是必要的=--exclude因为 shell 扩展的结果需要是两个单词--exclude=*.jpgand --exclude=*.mp4。如果没有=,扩展将是三个单词:--exclude*.jpg*.mp4

相关内容