Dado este pedazo de fiesta:
PARMS='-rvu'
PARMS+=" --delete --exclude='.git'"
echo $PARMS
rsync ${PARMS} . ${TARGET}
El eco muestra la cadena PARMS como se esperaba, no se muestra ningún error, pero rsync actúa silenciosamente como si las opciones agregadas por + = no existieran. Sin embargo, esto funciona como se esperaba:
PARMS='-rvu'
rsync ${PARMS} --delete --exclude='.git' . ${TARGET}
Supongo que arruiné algo con citas bash (siempre tuve problemas con eso), pero no estoy seguro de qué y por qué se ignoran las opciones a pesar de que la cadena parece haber sido construida correctamente.
echo "$PARMS"
yrsync "${PARMS}"
...bash
versión 4.2.25 sin ningún cambio.Respuestas:
Hay una diferencia entre:
y
En el primero, las comillas simples son comillas internas, por lo que están literalmente presentes en el texto sustituido dado
rsync
como argumentos.rsync
obtiene un argumento cuyo valor es--exclude='.git'
. En el segundo, las comillas simples son interpretadas por el shell en el momento en que se escriben, porque no están dentro de las comillas yrsync
pueden ver--exclude=.git
.En este caso, no necesita las comillas simples:
.git
es una palabra de shell perfectamente válida por sí sola, sin caracteres especiales, por lo que puede usarla literalmente en el comando.Sin embargo, mejor para este tipo de cosas es una matriz :
Esto construye su comando como palabras separadas, con cualquier cita que desee interpretada en el momento en que escribe la línea de matriz.
"${PARMS[@]}"
se expande a cada entrada de la matriz como un argumento separado, incluso si el argumento en sí tiene caracteres especiales o espacios, porrsync
lo que ve lo que escribió tal como lo dijo.fuente
bash
realizó la división de palabras después de que${PARMS}
se expandió. Entonces la cita simple también fue interpretada por el shell.\
,'
y"
. Que no resultó de una de las expansiones anteriores se eliminan" "expansiones anteriores" incluye la expansión de parámetros que realiza la expansión de${PARMS}
.IFS
(generalmente, espacios en blanco), no necesita citarlos. Si lo están, no tienes suerte a menos que hackees algo con éleval
, esto es un poco un error en general, y las matrices son la forma correcta de lidiar con eso.Además de la respuesta de @Michael Homer , puede usar la
bash
función eval :fuente
eval
.