rsync --delete eliminó la mayoría de los archivos en el directorio de destino, ¿por qué?

rsync --delete eliminó la mayoría de los archivos en el directorio de destino, ¿por qué?

Tengo /etctodos mis archivos de configuración en la carpeta en mal estado porque no me ocupé de la expansión del shell mientras hacía rsync:

rsync --progress --delete -avhHe ssh /etc/logrotate.d/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} [email protected]:/etc

Creo que el problema es que el '.' El siguiente logrotate se expandió y posteriormente /etc/httpdse eliminaron algunas carpetas, como por ejemplo .

Quiero aprender de este error haciéndolo correctamente. ¿Cómo evito la expansión del shell cuando sincronizo varios archivos con ssh?

Respuesta1

Ese comando se reduce a esto:

rsync --delete --recursive /etc/logrotate.d/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} [email protected]:/etc

El ."in" tiene un significado literal, es parte del nombre, así que ese no es el problema. La parte en {}está sujeta aexpansión de corsé: cada parte separada por comas se expande y se concatena con la parte de ese argumento anterior ( /etc/logrotate.d/). (También obtendría algo después, si hubiera algo: a{BC}dse expande a aBd aCd).

Entonces este comando es equivalente a

rsync --delete --recursive /etc/logrotate.d/httpd /etc/logrotate.d/mariadb /etc/logrotate.d/php-fpm /etc/logrotate.d/ppp /etc/logrotate.d/wpa_supplicant /etc/logrotate.d/yum [email protected]:/etc

o elegir solo un directorio para que sea breve:

rsync --delete --recursive /etc/logrotate.d/httpd [email protected]:/etc

rsync interpreta la ubicación "de" como una entidad única, y sinotermina con a, /crea un nuevo archivo o directorio con solo la última parte de ese nombre dentro de la ruta de destino dada: aquí, eso es httpd. Entonces esto crea un /etc/httpddestino y copia el contenido /etc/logrotate.d/httpden él.

Con --delete, entonces seráelimina todoesono fueen /etc/logrotate.d/httpdla fuente. El problema: dado que /etc/logrotate.d/httpdprobablemente no exista en absoluto, copiarlo y eliminar cualquier archivo que no estuviera presente en el origen significaeliminando todo en todos esos directorios. Si existiera, su contenido no será el mismo que el de /etc/httpd, por lo que (casi) todo será eliminado.

Entonces, el problema es que tienes la logrotate.dparte allí, cuando en realidad querías copiar los mismos directorios en /etc. Lo que probablemente quisiste decir fue simplemente:

rsync --progress --delete -avhHe ssh /etc/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} [email protected]:/etc

Eso copia /etc/httpdy su contenido /etc/httpden el destino, y así sucesivamente. Si querías copiar cosas del interior logrotate.d, colócalas en el camino a ambos lados.

Una cosa que puede resultarle útil es la-nu --dry-runopcióna rsync:

-n, --dry-run realiza una ejecución de prueba sin realizar cambios

Eso le mostrará una vista previa de lo que sucedería, pero en realidad no realizará ningún cambio en ninguno de los extremos. Puede usarlo para verificar que es lo que desea antes de ejecutar el programa real.


Preguntaste cómo evitar la expansión del shell en los argumentos que diste a rsync. Como se indicó anteriormente, no creo que eso sea realmente lo que desea dado el problema que tuvo, pero si alguna vez lo necesita: las expansiones de llaves no se realizan entre comillas, por lo que "a{BC}d"permanecen a{BC}dliteralmente.

información relacionada