这是运行 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
,但请注意:
这是一个外壳特征被称为支撑扩张。这是不是rsync 或 rsync 过滤规则的一个功能。
如果您错误地认为 rsync 将使用大括号本身(它不会,也不能,甚至永远不会看到大括号),这很容易导致混乱和“令人惊讶”的行为。
扩展完成前rsync 被执行。 rsync 只能看到,例如,
--exclude=*.mp4
因为当前目录中没有与该模式匹配的文件名。万一有任何文件名匹配
--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=*.jpg
and --exclude=*.mp4
。如果没有=
,扩展将是三个单词:--exclude
、*.jpg
和*.mp4
。