Tengo /etc
todos 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/httpd
se 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}d
se 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/httpd
destino y copia el contenido /etc/logrotate.d/httpd
en él.
Con --delete
, entonces seráelimina todoesono fueen /etc/logrotate.d/httpd
la fuente. El problema: dado que /etc/logrotate.d/httpd
probablemente 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.d
parte 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/httpd
y su contenido /etc/httpd
en 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-n
u --dry-run
opció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}d
literalmente.