rsync: ¿Cómo excluir varios tipos de archivos?

rsync: ¿Cómo excluir varios tipos de archivos?

Esto es con bash en una Mac con Catalina:

Esto funciona:

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

Estos no:

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 es la salida:

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]

¿Qué estoy haciendo mal con la lista de tipos de archivos para excluir?

Respuesta1

En primer lugar, su primer ejemplo funciona: ¿qué hay de malo en usarlo?

Si realmente no quieres hacer eso, prueba --exclude=*.{jpg,mp4}, que (en algunos shells) se expandirá a --exclude=*.jpg --exclude=*.mp4, pero ten en cuenta:

  1. esto es uncaracterística del caparazónllamadoExpansión de llaves. Esnouna característica de rsync o las reglas de filtro de rsync.

    Esto puede generar fácilmente confusión y un comportamiento "sorprendente" si piensa erróneamente que rsync usará las llaves (no lo hará, no puede hacerlo y ni siquiera ve las llaves).

  2. La expansión está hecha.antesSe ejecuta rsync. rsync solo ve, por ejemplo, --exclude=*.mp4 porqueno hay ningún nombre de archivo que coincida con ese patrón en el directorio actual.

  3. en el improbable caso de que haya nombres de archivos que coincidan con --exclude=*.mp4o --exclude=*.jpg, la expansión de llaves se expandirá a esos nombres de archivos exactos, sin comodines.

p.ej

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

Hasta ahora, todo bien... pero mira lo que sucede cuando hay nombres de archivos que realmente coinciden con las expansiones de llaves:

$ 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

Una mejor manera de evitar escribir muchas --excludeopciones sería usar una matriz e imprimir:

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

Esto daría como resultado una línea de comando como:

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

Aún mejor sería utilizar una matriz y una sustitución de procesos para proporcionar un "archivo" para --exclude-from. p.ej

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

Respuesta2

--exclude={'*.jpg', '*.mp4'}no lo haceexpansión de corséporque las llaves de apertura y cierre están en palabras separadas. La expansión de llaves construye varias palabras a partir de una sola palabra con una parte variable. Retire el espacio.

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

o

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

El =después --excludees necesario porque el resultado de la expansión del shell debe ser las dos palabras --exclude=*.jpgy --exclude=*.mp4. Sin a =, la expansión sería de tres palabras --exclude: *.jpgy *.mp4.

información relacionada