O diretório de exclusão rsync não está funcionando

34

Estou executando o Fedora 17 de 64 bits e rsync --exclude=/home/ben/<dir>não está funcionando conforme o esperado.

Estou tentando rsyncmeu diretório pessoal em um pen drive, mas quero excluir certamente os diretórios que contêm arquivos em cache e os compilam. Este é o comando que estou usando:

rsync --exclude=/home/ben/build/ --exclude=/home/ben/.ccache -arv /home/ben home-ben/

No entanto, o conteúdo do ~/builde ~/.ccacheestá sendo copiado por rsync. O que estou fazendo errado?

Freedom_Ben
fonte
1
Eu acho que os padrões de exclusão simplesmente não funcionam.
Sören

Respostas:

37

As rsyncregras globais de filtro que começam com um líder /estão ancoradas na raiz da transferência. Citando a seção "INCLUIR / EXCLUIR REGRAS DE PADRÃO" da página do manual:

se o padrão começar com um /, ele será ancorado em um ponto específico na hierarquia de arquivos; caso contrário, será comparado com o final do nome do caminho. Isso é semelhante a um ^ inicial em expressões regulares. Assim, "/ foo" corresponderia ao nome "foo" na "raiz da transferência" (para uma regra global) ou no diretório do arquivo de mesclagem (para uma regra por diretório).

No seu comando ( rsync ... -arv /home/ben home-ben/), o arquivo /home/ben/fooseria transferido para home-ben/ben/foo. A raiz da transferência é home-bene o caminho correto do filtro é /ben/foo. Portanto,

  • para corresponder, /home/ben/.ccachevocê precisa de um caminho de filtro de/ben/.ccache
  • para corresponder, /home/ben/build/você precisa de um caminho de filtro de/ben/build/

Uma explicação mais detalhada pode ser encontrada na seção "ANCHORING INCLUDE / EXCLUDE PATTERNS" da rsync(1)página de manual .


Observe que simplesmente deixar de fora a liderança /não é necessariamente o que você deseja. Citando novamente a mesma seção da página de manual:

Um "foo" não qualificado corresponderia a um nome de "foo" em qualquer lugar da árvore porque o algoritmo é aplicado recursivamente de cima para baixo; ele se comporta como se cada componente do caminho chegasse ao final do nome do arquivo. Até o "sub / foo" não ancorado corresponderia em qualquer ponto da hierarquia em que um "foo" fosse encontrado dentro de um diretório chamado "sub". Consulte a seção ANCHORING INCLUDE / EXCLUDE PATTERNS para obter uma discussão completa de como especificar um padrão que corresponda à raiz da transferência.

Assim, um padrão de filtro build/corresponderia a um diretório de compilação em qualquer lugar /home/ben, inclusive /home/ben/many/sub/directories/build/.

jw013
fonte
2
O detalhe principal é que as barras são importantes. Se você anexar uma barra no final do diretório de origem (rsync -a source / destination), ele copiará o conteúdo da fonte, caso contrário, rsync -a source destinationcopiará o próprio diretório de origem para o destino. Isso determina qual será a raiz da transferência para informar a expressão de exclusão. O uso adequado de / na expressão de exclusão é explicado acima. Observe em particular que rsync --exclude='/dir1' source destinationnão excluirá nada.
pgoetz
11

Eu acho que seus excludecaminhos precisam ser relativos ao caminho de origem. Você pode tentar isso?

rsync --exclude=build/ --exclude=.ccache -arv /home/ben home-ben/

Aqui está um teste, para comparação:

/tmp$ tree src dest
src
├── a
└── b
dest
└── foo/

/tmp$ rsync -nav --exclude /tmp/src/b /tmp/src /tmp/dest
sending incremental file list
src/
src/a
src/b

$ rsync -nav --exclude b /tmp/src /tmp/dest
sending incremental file list
src/
src/a
CavaloPunchKid
fonte
2
Esta resposta está errada. Com um caminho de exclusão relativo, você excluiria o padrão em qualquer lugar!
rubo77
Esta postagem está correta. A correspondência é baseada em texto, não em arquivo. Qualquer que seja o caminho exibido pela saída do --verbosecomando, é o formato que você deve usar.
Sridhar Sarnobat
Isso funcionou para mim.
Zhenyu 28/05
E se o caminho de origem for '/' absoluto, são os caminhos relativos, mas ainda não funcionam.
Sören
Esta é a única coisa que funcionou para mim.
Jonathan
2

Eu tive esse problema em um script (não sei se é o seu caso). Eu usei esse comando em um script e estava usando sh em vez de bash. verifique o shebang no início do seu script.

Jaoued Zahraoui
fonte
1

Seu padrão de exclusão funcionaria se você sincronizar o caminho inteiro / inicial, ou seja, sem uma barra final:

rsync --exclude=/home/ben/build/ --exclude=/home/ben/.ccache -arv /home home-all/

Mas melhor apenas sincronizar o conteúdo da pasta com uma barra à direita:

rsync --exclude=/build --exclude=/.ccache -arv /home/ben/ home-ben/

Você também pode usar uma lista de ignorados, consulte: https://askubuntu.com/questions/545655/backup-your-home-directory-with-rsync-and-skip-useless-folders

rubo77
fonte
0

Para excluir uma pasta specif com o rsync, é necessário considerar o caminho relativo no comando. no seu caso:

rsync --exclude=/ben/build/ --exclude=/ben/.ccache -arv /home/ben home-ben/

onde "ben" é a pasta que você está sincronizando

Samoht Rusconi
fonte