O GNU tar
tem uma opção -T
para obter a lista de arquivos de um arquivo especificado. Eu usaria find ... -print0 | tar cfzT outfile.tgz - --null
então tar
receber nomes de arquivos terminados com nulo em stdin
.
Eu gostaria de criar um tarball que contenha arquivos de um diretório que tenha ctime de menos de 30 dias. A maioria dos tutoriais que eu encontrei basicamente recomendou fazer algo assim:
tar cvf foo.tar $(find ~/POD -type f -ctime -30)
O problema é que muitos dos arquivos que eu quero incluir contêm espaços em seus nomes. Isso significa que o comando tar
delimitará com base em espaços, o que significa que os caminhos completos dos arquivos serão divididos.
Agora, estou tentando fazer com que o comando find
retorne uma lista de caminhos de arquivos entre aspas. Então, aqui está o que eu tentei:
find . -type f -ctime -30 | xargs printf "\"%s\"\n"
Mas este comando também quebrou todos os nomes de arquivos baseados em espaços. Então tentei isso:
oldifs=$IFS
IFS=\n
find . -type f -ctime -30 | xargs printf "\"%s\"\n"
IFS=$oldifs
Mas isso me deu os mesmos resultados.
Existe uma maneira de passar os nomes dos caminhos completos para tar
e ter tudo funcionando com espaços em seus nomes?
A saída com terminação nula é canalizada para tar
sugerido pelo geekosaur deve fazer o truque, mas você também pode fazer isso com a opção -exec
de find. Find sabe que este é um problema difícil, então eles resolveram isso, você só precisa reverter as coisas do que tentou fazer com tar … $(find …)
e usar find
para chamar tar
assim:
find . -type f -ctime -30 -exec tar cfz outfile.tgz {} +
Você quase teve. Você precisa escapar \ n como $ '\ n' para atribuir uma nova linha a uma variável.
oifs=$IFS; IFS=$'\n'; tar cvf foo.tar $(find ~/POD -type f -ctime -30); IFS=$oifs
Veja a seção Quotes da página man do bash para mais informações.
Tags tar linux unix shell-scripting