Eu tenho meus arquivos de configuração na /etc
pasta bagunçados porque não cuidei da expansão do shell ao fazer o rsync:
rsync --progress --delete -avhHe ssh /etc/logrotate.d/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} [email protected]:/etc
Acho que o problema é que o '.' o logrotate seguinte foi expandido e, posteriormente, algumas pastas, como /etc/httpd
foram excluídas.
Quero aprender com esse erro fazendo-o corretamente. Como evito a expansão do shell ao sincronizar vários arquivos com ssh?
Responder1
Esse comando se resume a isto:
rsync --delete --recursive /etc/logrotate.d/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} [email protected]:/etc
O .
dentro tem seu significado literal - faz parte do nome - então esse não é o problema. A parte {}
está sujeita aexpansão de cinta: cada parte separada por vírgula é expandida e concatenada à parte do argumento que veio antes ( /etc/logrotate.d/
). (Também receberia qualquer coisa depois, se houvesse alguma coisa: a{BC}d
expande para aBd aCd
).
Portanto, este comando é 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
ou escolher apenas um diretório para que seja curto:
rsync --delete --recursive /etc/logrotate.d/httpd [email protected]:/etc
rsync interpreta o local "de" como uma entidade única e, se fornãoterminar com a /
cria um novo arquivo ou diretório com apenas a última parte desse nome dentro do caminho de destino fornecido: aqui, é httpd
. Então isso faz um /etc/httpd
no destino e copia o conteúdo /etc/logrotate.d/httpd
nele.
Com --delete
, será entãodeletar tudoquenão foina /etc/logrotate.d/httpd
fonte. O problema - já que /etc/logrotate.d/httpd
provavelmente não existe, copiá-lo e excluir todos os arquivos que não estavam presentes na fonte significaexcluindo tudo em todos esses diretórios. Se existisse, seu conteúdo não será igual ao /etc/httpd
, então (quase) tudo será deletado.
Portanto, o problema é que você tem a logrotate.d
parte lá, quando na verdade pretendia copiar os mesmos diretórios em /etc
. O que você provavelmente quis dizer foi apenas:
rsync --progress --delete -avhHe ssh /etc/{httpd,mariadb,php-fpm,ppp,wpa_supplicant,yum} [email protected]:/etc
Isso copia /etc/httpd
e seu conteúdo para /etc/httpd
o destino e assim por diante. Se você pretendia copiar coisas dentro logrotate.d
, coloque isso no caminho em ambos os lados.
Uma coisa que você pode achar útil é o-n
ou --dry-run
opçãopara rsync
:
-n, --dry-run executa uma execução de teste sem nenhuma alteração feita
Isso mostrará uma prévia do que aconteceria, mas não fará nenhuma alteração em nenhuma das extremidades. Você pode usar isso para verificar se é o que deseja antes de executar a coisa real.
Você perguntou como evitar a expansão do shell nos argumentos que forneceu rsync
. Como acima, não acho que seja isso que você deseja, dado o problema que teve, mas se precisar: as expansões de chaves não ocorrem entre aspas, portanto "a{BC}d"
permanecem a{BC}d
literalmente.