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

相關內容