¿Cómo uso una variable Bash (cadena) que contiene comillas en un comando?

45

Error, ejemplo simplificado:

FLAGS='--archive --exclude="foo bar.txt"'
rsync $FLAGS dir1 dir2

Necesito incluir las comillas como si el comando fuera así:

rsync --archive --exclude="foo bar.txt" dir1 dir2
Reilly Beacom
fuente

Respuestas:

56

Respuesta corta: vea BashFAQ # 50 ("Estoy tratando de poner un comando en una variable, ¡pero los casos complejos siempre fallan!").

Respuesta larga: poner comandos (o partes de comandos) en variables y luego recuperarlos intactos es complicado. Cuando el shell expande una variable en la línea de comando, si la variable estaba entre comillas dobles no se analiza; si no estaba entre comillas, los espacios se analizan como saltos de argumento, pero las comillas y el escape no se analizan. En cualquier caso, poner comillas en el valor de la variable no hace nada útil.

Por lo general, la mejor manera de hacer este tipo de cosas es usar una matriz en lugar de una simple variable de texto:

FLAGS=(--archive --exclude="foo bar.txt")
rsync "${FLAGS[@]}" dir1 dir2
Gordon Davisson
fuente
Santo Jezus funciona!
Slawomir
-2

No veo el problema :

$ FLAGS='--archive --exclude="foo bar.txt"'
$ echo $FLAGS
--archive --exclude="foo bar.txt"

Tal vez necesite citar nuevamente el valor:

$ rsync "$FLAGS" dir1 dir2
Franck Lefort
fuente
55
echono muestra lo que crees que es. Intente printargs() { printf "'%s' " "$@"; echo; }; printargs $FLAGS; printargs "$FLAGS"ver por qué ninguna de estas opciones funciona.
Gordon Davisson el