rsync: Como excluir vários tipos de arquivo?

rsync: Como excluir vários tipos de arquivo?

Isto ocorre com o bash em um Mac rodando Catalina:

Isso funciona:

rsync -Pa --rsh="ssh -p 19991" --exclude '*.jpg' --exclude '*.mp4' pi@localhost:/home/pi/webcam /Volumes/Media/Webcam\ Backups/raspcondo/webcam/

Estes não:

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/

Esta é a saída:

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]

O que estou fazendo de errado com a lista de tipos de arquivos a serem excluídos?

Responder1

Primeiro de tudo, o seu primeiro exemplo funciona - o que há de errado em usar isso?

Se você realmente não quiser fazer isso, tente --exclude=*.{jpg,mp4}, que será (em alguns shells) expandido para --exclude=*.jpg --exclude=*.mp4, mas observe:

  1. isto é umrecurso de shellchamadoExpansão de cinta. Isso énãoum recurso do rsync ou das regras de filtro do rsync.

    Isso pode facilmente levar à confusão e ao comportamento "surpreendente" se você pensar erroneamente que o rsync usará os colchetes em si (ele não usará, não poderá e nunca verá os colchetes).

  2. A expansão está feitaantesrsync é executado. rsync só vê, por exemplo, --exclude=*.mp4 porquenão há nome de arquivo que corresponda a esse padrão no diretório atual.

  3. no caso improvável de haver nomes de arquivos que correspondam a --exclude=*.mp4ou --exclude=*.jpg, a expansão das chaves será expandida para esses nomes de arquivos exatos, sem um curinga.

por exemplo

$ mkdir /tmp/test
$ cd /tmp/test
$ echo rsync --exclude=*.{jpg,mp4}
rsync --exclude=*.jpg --exclude=*.mp4

até agora, tudo bem... mas veja o que acontece quando há nomes de arquivos que realmente correspondem às expansões de chaves:

$ 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

A melhor maneira de evitar digitar muitas --excludeopções seria usar um array e printf:

excludes=('*.mp4' '*.jpg')
rsync ...args... $([ "${#excludes[@]}" -gt 0 ] && printf -- "--exclude='%s' " "${excludes[@]}") ...more args...

Isso resultaria em uma linha de comando como:

rsync ...args... --exclude='*.mp4' --exclude='*.jpg'  ...more args...

Melhor ainda seria usar uma matriz e uma substituição de processo para fornecer um "arquivo" para --exclude-from. por exemplo

rsync ... --exclude-from=<([ "${#excludes[@]}" -gt 0 ] && printf -- '- %s\n' "${excludes[@]}") ... 

Responder2

--exclude={'*.jpg', '*.mp4'}não fazexpansão de cintaporque os colchetes de abertura e fechamento estão em palavras separadas. A expansão de chaves cria várias palavras a partir de uma única palavra com uma parte variável. Remova o espaço.

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

ou

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

O =after --excludeé necessário porque o resultado da expansão do shell precisa ser as duas palavras --exclude=*.jpge --exclude=*.mp4. Sem a =, a expansão teria três palavras --exclude: *.jpge *.mp4.

informação relacionada