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}これは (一部のシェルでは) に展開されます--exclude=*.jpg --exclude=*.mp4が、次の点に注意してください。

  1. これはシェル機能と呼ばれるブレース拡張それはないrsync の機能または 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'}しないブレース拡張開き括弧と閉じ括弧が別々の単語にあるためです。括弧の展開により、可変部分を持つ 1 つの単語から複数の単語が作成されます。スペースを削除します。

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

または

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

シェル展開の結果は と という 2 つの単語になる必要があるため、の後=に が必要です。 がない場合、展開は 、 、 の 3 つの単語になります。--exclude--exclude=*.jpg--exclude=*.mp4=--exclude*.jpg*.mp4

関連情報