rsync --delete excluiu a maioria dos arquivos no diretório de destino, por quê?

1

Eu tenho meus arquivos de configuração na pasta /etc , todos confusos porque eu não cuidei da expansão do shell enquanto fazia o rsync:

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

Eu acho que o problema é que o '.' Depois logrotate foi expandido e, posteriormente, algumas pastas, como /etc/httpd foi excluído.

Eu quero aprender com esse erro fazendo isso corretamente. Como faço para evitar a expansão do shell quando rsync vários arquivos com ssh?

    
por Question Overflow 22.06.2014 / 11:21

1 resposta

3

Esse comando resume-se a isto:

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

O . tem seu significado literal - é parte do nome - então esse não é o problema. A parte em {} está sujeita à expansão de chaves : cada uma separada por vírgulas parte é expandida e concatenada à parte do argumento que veio antes ( /etc/logrotate.d/ ). (Também ganharia algo depois, se houvesse algo: a{BC}d se 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 para escolher apenas um diretório, por isso é curto:

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

O rsync interpreta o local "de" como uma entidade única e, se não terminar com / , cria um novo arquivo ou diretório com apenas a última parte desse nome dentro o caminho de destino indicado: aqui, isso é httpd . Então, isso faz um /etc/httpd no destino e copia o conteúdo de /etc/logrotate.d/httpd para ele.

Com --delete , será excluir tudo que não foi em /etc/logrotate.d/httpd na origem. O problema - como /etc/logrotate.d/httpd provavelmente não existe, copiá-lo e excluir todos os arquivos que não estavam presentes na origem significa excluir tudo em todos esses diretórios . Se ele existisse, seu conteúdo não seria o mesmo que /etc/httpd , então (quase) tudo seria deletado.

Portanto, o problema é que você tem a parte logrotate.d , quando realmente queria 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 no destino e assim por diante. Se você quisesse copiar as coisas dentro de logrotate.d , coloque isso no caminho dos dois lados.

Uma coisa que você pode achar útil é a -n ou --dry-run opção para rsync :

-n, --dry-run perform a trial run with no changes made

Isso mostrará uma prévia do que aconteceria, mas não fará alterações nos dois lados. Você pode usar isso para verificar o que você quer antes de executar a coisa real.

Você perguntou como evitar a expansão do shell nos argumentos que você deu a rsync . Como acima, eu não acho que é realmente o que você quer dado o problema que você teve, mas se você precisar: expansões de chaves não ocorrem dentro de aspas, então "a{BC}d" fica como a{BC}d literalmente.

    
por 22.06.2014 / 11:57

Tags