2009-05-11 8 views
7

que tienen una sencilla prueba de escritura del golpe que se parece a lo siguiente:script del archivo contra de línea de comandos: rsync y --exclude

#!/bin/bash 

cmd="rsync -rv --exclude '*~' ./dir ./new" 
$cmd # execute command 

Cuando ejecuto el guión se copia también los archivos que terminan con un ~ a pesar de que quise excluirlos. Cuando ejecuto el mismo comando rsync directamente desde la línea de comandos, ¡funciona! ¿Alguien sabe por qué y cómo hacer funcionar el script bash?

Btw, sé que también puedo trabajar con --exclude-from pero quiero saber cómo funciona esto de todos modos.

Respuesta

5

Trate eval:

#!/bin/bash 

cmd="rsync -rv --exclude '*~' ./dir ./new" 
eval $cmd # execute command 
0

Se puede utilizar un simple --eclude '~' como (accoding a la página del manual):

  • si el patrón comienza con un/a continuación, que está anclado a un punto particular en la jerarquía de archivos, de lo contrario se compara con el final del nombre de ruta . Esto es similar a un ^ en expresiones regulares. Por lo tanto, "/ foo" coincidiría con el nombre de "foo" en la "raíz de la transferencia" (para una regla global ) o en el directorio del archivo merge (para una regla por directorio). Un "foo" no calificado coincidiría con un nombre de "foo" en cualquier parte del árbol porque el algoritmo se aplica recursivamente de arriba hacia abajo; se comporta como si cada componente de ruta obtiene como el final del nombre de archivo . Incluso el no anclado "sub/foo" coincidiría en cualquier punto en la jerarquía donde se encontró un "foo" dentro de un directorio llamado "sub". Consulte la sección sobre ANCLAJE PATRONES DE INCLUIR/EXCLUIR para una discusión completa de sobre cómo especificar un patrón que coincida con la raíz de la transferencia .
  • si el patrón finaliza con a/y solo coincidirá con un directorio, no con un archivo normal , un enlace simbólico o un dispositivo.
  • rsync elige entre hacer una coincidencia de cadena simple y un comodín haciendo coincidir al comprobar si el patrón contiene uno de estos tres comodines caracteres: '*', '?' Y '['.
  • a '*' coincide con cualquier componente de ruta, pero se detiene en barras inclinadas.
  • usa '**' para hacer coincidir cualquier cosa, incluidas las barras diagonales.
4

El problema es que no se está ejecutando en un script, es que se pone el comando en una variable y luego ejecuta la variable expandida . Y dado que la expansión de variables ocurre una vez que se ha eliminado la cita, las comillas simples alrededor de su patrón de exclusión nunca se eliminan ... y así rsync termina excluyendo archivos con nombres que comienzan con 'y terminan con ~'.Para solucionar este problema, basta con retirar las comillas alrededor del patrón (todo el asunto ya está en comillas dobles, por lo que no son necesarios):

#!/bin/bash 

cmd="rsync -rv --exclude *~ ./dir ./new" 
$cmd # execute command 

... Hablando de eso, ¿por qué estás poniendo el comando en una variable antes de ejecutarlo? En general, esta es una buena manera de hacer que el código sea más confuso de lo necesario y desencadenar el análisis de rarezas (algunos incluso más extraños que este). Entonces, ¿qué tal:

#!/bin/bash 

rsync -rv --exclude '*~' ./dir ./new 
+0

Lo puse en una variable para depurar. Comencé sin comillas simples y eso fue incluso peor (de hecho, es por eso que los puse allí) debido a la expansión. P.ej. "rsync -r --exclude * ~ ./dir ./new" expandido a "rsync -r --excluir foo ~ bar ~ foobar.sh ~ ./dir ./new" – Chris

+0

¿Lo intentó con las comillas simples, pero sin ponerlo en una variable (como en mi segunda recomendación)? Debería funcionar bien (y parecía cuando lo probé). –

Cuestiones relacionadas