Bua*_*hai 4 bash rsync brace-expansion
这是运行 Catalina 的 Mac 上的 bash:
这有效:
rsync -Pa --rsh="ssh -p 19991" --exclude '*.jpg' --exclude '*.mp4' pi@localhost:/home/pi/webcam /Volumes/Media/Webcam\ Backups/raspcondo/webcam/
Run Code Online (Sandbox Code Playgroud)
这些不:
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/
Run Code Online (Sandbox Code Playgroud)
这是输出:
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]
Run Code Online (Sandbox Code Playgroud)
我对要排除的文件类型列表做错了什么?
首先,你的第一个例子是有效的——使用它有什么问题吗?
如果您确实不想这样做,请尝试--exclude=*.{jpg,mp4},它将(在某些 shell 中)扩展为--exclude=*.jpg --exclude=*.mp4,但请注意:
这是一个名为Brace Expansion的shell 功能。它不是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
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好...但是看看当文件名与大括号扩展实际匹配时会发生什么:
$ 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
Run Code Online (Sandbox Code Playgroud)
避免输入大量--exclude选项的更好方法是使用数组和 printf:
excludes=('*.mp4' '*.jpg')
rsync ...args... $([ "${#excludes[@]}" -gt 0 ] && printf -- "--exclude='%s' " "${excludes[@]}") ...more args...
Run Code Online (Sandbox Code Playgroud)
这将产生如下命令行:
rsync ...args... --exclude='*.mp4' --exclude='*.jpg' ...more args...
Run Code Online (Sandbox Code Playgroud)
更好的是使用数组和进程替换来为--exclude-from. 例如
rsync ... --exclude-from=<([ "${#excludes[@]}" -gt 0 ] && printf -- '- %s\n' "${excludes[@]}") ...
Run Code Online (Sandbox Code Playgroud)