A opção Rsync --delete não exclui arquivos no diretório de destino

14

Estou tentando usar a --deleteopção rsyncpara excluir arquivos no diretório de destino que não estão presentes no diretório original

Aqui está o comando que estou usando:

rsync -avz --ignore-existing --recursive --delete /var/www/* root@mydomaintest.com:/var/www

Portanto, minha pergunta é: como posso excluir todos os arquivos no diretório de destino que não estão presentes no diretório original?

user2028856
fonte

Respostas:

14

Use este comando:

rsync --archive --verbose --compress --ignore-existing --delete /var/www/ root@mydomaintest.com:/var/www

Você não precisa de um "*" e também não deve usá-lo.

Para excluir / incluir arquivos ou diretórios, você deve usar estes parâmetros:

--exclude 'to_exclude*'
--include 'to_include*'
AB
fonte
Ok, deixe-me tentar este :)
user2028856
2
Então o "*" que está causando o comando --delete não está funcionando?
usar o seguinte comando
2
É assim que parece. :)
AB
3
--recursiveé abundante porque a opção -ajá inclui-lo
Temak
1
O "*" pode ser importante em alguns casos, porque exclui arquivos / diretórios que começam com ".". Por exemplo, eu o uso ao usar o rsync para copiar um diretório mantido no git de uma máquina de desenvolvimento para uma máquina de produção. Não quero sincronizar o diretório do repositório .git ou arquivos como .gitignore, apenas a árvore de trabalho, incluindo arquivos no nível superior e subdiretórios.
sootsnoot
14

Seu comando não estava funcionando porque, quando você estava usando /var/www/*como fonte, seu shell está exibindo um brilho nele, ou seja, o shell está se expandindo *para todos os arquivos desse diretório e copiando os arquivos um por um, então aqui os arquivos individuais se tornaram as fontes em vez de o diretório pai.

Então, se você usar /var/www/* , não precisará da --recursiveopção, pois *fará com que os arquivos sejam copiados (junto com os diretórios com seu conteúdo), não o diretório pai que contém os arquivos. Pelo mesmo motivo, --deletenão está funcionando, pois --deleteremoverá os arquivos do diretório de destino que não estão no diretório de origem , mas você está copiando os arquivos para que não os remova (como esperado).

Isso tornará você mais claro:

/foo$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test


/bar$ ls -l
-rw-rw-r-- 1 user user 0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user 0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user 0 Apr 16 17:56 spam


$ rsync -avz --ignore-existing --recursive --delete 
/foo/* /bar/

+ rsync -avz --ignore-existing --recursive --delete 
/foo/egg /foo/spam /foo/test /bar/

sending incremental file list
test/
test/hello

sent 173 bytes  received 39 bytes  424.00 bytes/sec
total size is 0  speedup is 0.00


/bar$ ls -l
-rw-rw-r-- 1 user user    0 Apr 16 17:56 egg
-rw-rw-r-- 1 user user    0 Apr 16 18:13 lion
-rw-rw-r-- 1 user user    0 Apr 16 17:56 spam
drwxrwxr-x 2 user user 4096 Apr 16 18:14 test

Como você pode ver, eu usei a fonte, /foo/*portanto, o rsynccomando que está sendo executado é

rsync -avz --ignore-existing --recursive --delete /foo/egg 
/foo/spam /foo/test /bar/

com *fazer shell para expandi-lo e criar todos os arquivos individualmente como argumentos de origem, não o diretório pai como um todo (e você também não precisa --recursiveneste caso).

Portanto, se você quiser fazer o --deletetrabalho, execute-o como:

rsync -avz --ignore-existing --recursive --delete 
/var/www/ root@mydomaintest.com:/var/www/
heemail
fonte
4
Excelente explicação apontando o problema real: usando '*' para expandir a lista de fontes.
Antonio Bardazzi 08/07/19
Conforme observado no meu comentário sobre a resposta aceita, o * pode ser útil para excluir itens como arquivos e diretórios começando com ".". Embora, como você observa, isso signifique que arquivos e diretórios removidos do nível superior da fonte não serão removidos do diretório de destino. Para mim, não me importo se os arquivos de nível superior são excluídos corretamente do destino, apenas os arquivos abaixo dos subdiretórios são importantes. A remoção de um subdiretório de nível superior é muito menos provável do que a adição de um, e eu estou disposto a fazer um manual rm -r no destino nesse caso improvável.
sootsnoot