'find -mtime -1 -print | xargs tar 'arquiva todos os arquivos do diretório ignorando o argumento -mtime -1

4

Estou tentando criar um script de backup. Eu consegui fazer este script funcionar bem em uma máquina CentOS 6.7 e agora estou tentando fazer com que ele funcione corretamente no Debian 7.

Estou com um problema que não consigo resolver com o Google ou qualquer informação encontrada neste site. Eu tentarei explicar minha situação antes de entrar no problema.

No CentOS, eu uso o seguinte comando para encontrar arquivos que foram alterados nas últimas 24 horas em $SOURCEDIR e use xargs para colocar apenas esses arquivos em $ARCHIVE . Se nenhum arquivo for encontrado, uma mensagem será exibida.

find $SOURCEDIR -mtime -1 -print | xargs -r tar rcvf $ARCHIVE || { echo "No files have been changed in the past 24 hours. Exiting script ..." ; exit 1; }

Estou ciente de que usar tar rcvf pode invocar a seguinte mensagem de erro:

You may not specify more than one '-Acdtrux' or '--test-label' option

No entanto, isso não parece acontecer na máquina do CentOS. Ele faz na máquina Debian, assim eu removi o comando r do comando tar . A razão pela qual eu adicionei isso em primeiro lugar é porque eu quero evitar que o arquivo seja sobrescrito se find retornasse mais de 100 resultados.

Agora para o problema real. Sempre que eu corro

find $SOURCEDIR -mtime -1 -print

Eu recebo uma lista dos arquivos que foram alterados em $SOURCEDIR nas últimas 24 horas, como esperado. No entanto, sempre que eu executar o comando completo, incluindo o símbolo de pipe e o comando xargs , como este:

find $SOURCEDIR -mtime -1 -print | xargs -r tar cvf $ARCHIVE || { echo "No files have been changed in the past 24 hours. Exiting script ..." ; exit 1; }

Na verdade, vejo o comando find imprimir todos arquivos de $SOURCEDIR antes de acabar com um arquivo, incluindo todos os arquivos de $SOURCEDIR , e não entendo porque. Qualquer ajuda seria muito apreciada.

    
por Seroczynski 12.05.2016 / 15:35

4 respostas

2

Como outros já identificaram, o problema com o seu comando é que ele inclui diretórios, e o tar os arquiva recursivamente. Se um diretório foi modificado recentemente, todos os arquivos contidos nele e seus subdiretórios serão incluídos, tenham eles sido modificados ou não.

Se você não quiser fazer o backup dos metadados do diretório, basta informar find para não imprimir os nomes dos diretórios. Não é suficiente omitir a raiz: a mesma coisa pode acontecer com os subdiretórios também.

find "$SOURCEDIR" -mtime -1 ! -type d -print | xargs -r tar -rcf "$ARCHIVE"

Usando xargs falha com nomes de arquivos contendo espaços e alguns outros caracteres especiais . Isso é fácil de corrigir: use -exec em vez de xargs .

find "$SOURCEDIR" -mtime -1 ! -type d -exec tar -rcf "$ARCHIVE" {} +

Se você quiser fazer backup dos metadados do diretório, deixe find imprimir tudo e, em vez disso, informe tar para não recorrer aos subdiretórios. Como find está fazendo a recursão, tar não precisa.

find "$SOURCEDIR" -mtime -1 -exec tar -rcf "$ARCHIVE" --no-recursion {} +

Com essa abordagem, você pode evitar o uso de tar -rc e, em vez disso, resolver o problema de invocações repetidas de tar, primeiro criando um archive apenas com o diretório raiz e, em seguida, anexando-o a ele em lotes. (Por que o diretório raiz? Porque o tar GNU tem medo de criar um arquivo vazio.)

tar -cf "$ARCHIVE" --no-recursion "$SOURCEDIR"
find "$SOURCEDIR" -mindepth 1 -mtime -1 -exec tar -rf "$ARCHIVE" --no-recursion {} +
    
por 13.05.2016 / 01:26
2
find $SOURCEDIR -mtime -1

também inclui $SOURCEDIR na saída, que precisa ser removida antes de processamento adicional

Usando grep -vx , pode-se definir uma determinada linha a ser excluída.

find $SOURCEDIR -mtime -1 -print | grep -xv "$SOURCEDIR" | xargs -r tar cvf $ARCHIVE || { echo "No files have been changed in the past 24 hours. Exiting script ..." ; exit 1; }
    
por 12.05.2016 / 16:06
2

Você não só terá problemas se xargs invocar tar duas vezes, mas também terá problemas se os nomes dos arquivos contiverem caracteres especiais, como novas linhas.

Você deve desativar o uso de xargs e tar e usar find com cpio :

find $SOURCEDIR -mtime -1 -print0 | cpio --create -0 --verbose \
     --format=ustar -O $ARCHIVE

ustar fornece um arquivo tar compatível com POSIX.1 em $ARCHIVE .

    
por 12.05.2016 / 16:16
0

Quando você executar find $SOURCEDIR -mtime -1 -print terá como primeiro resultado a pasta $ SOURCEDIR propriamente dita. É por isso que tudo está incluído.
Você precisa excluir o primeiro resultado ou $SOURCEDIR .

    
por 12.05.2016 / 16:02