rsync: Как исключить несколько типов файлов?

rsync: Как исключить несколько типов файлов?

Это с помощью bash на Mac с установленной Catalina:

Это работает:

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 сам будет использовать фигурные скобки (он этого не сделает, не сможет и даже никогда их не увидит).

  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} …

После необходимо =, --excludeпоскольку результатом расширения оболочки должны быть два слова --exclude=*.jpgи --exclude=*.mp4. Без =, расширение будет состоять из трех слов: --exclude, *.jpgи *.mp4.

Связанный контент