Como tar o diretório e remover os originais, incluindo o diretório?


30

Estou tentando taruma coleção de arquivos em um diretório chamado 'my_directory' e remova os originais usando o comando:

tar -cvf files.tar my_directory --remove-files

No entanto, está apenas removendo os arquivos individuais dentro do diretório e não o próprio diretório (que é o que eu especifiquei no comando). O que estou perdendo aqui?

EDITAR:

Sim, suponho que a opção 'remover arquivos' seja bastante literal. Embora eu também ache a página de manual pouco clara nesse ponto. (No linux, eu não costumo distinguir muito isso entre diretórios e arquivos, e às vezes esqueço que eles não são a mesma coisa). Parece que o consenso é que ele não remove os diretórios.

No entanto, meu principal argumento para fazer essa pergunta decorre do manuseio de caminhos absolutos pelo tar. Como você deve especificar um caminho relativo para um arquivo / s a ​​ser compactado, você deve, portanto, mudar para o diretório pai para tarar corretamente. Na minha opinião, usar qualquer tipo de comando 'rm' subsequente é potencialmente perigoso nessa situação. Assim, eu esperava simplificar as coisas, fazendo o próprio tar remover.

Por exemplo, imagine um script de backup em que o diretório para backup (ou seja, tar) esteja incluído como uma variável do shell. Se esse valor da variável do shell tiver sido digitado incorretamente, é possível que o resultado possa ser excluído dos arquivos do diretório em que você esteve por último.


Nicholas, seu argumento de que isso adiciona perigo ao remover a árvore de diretórios em uma etapa extra é absolutamente válido. Eu acho que deveria ser possível fazer isso com segurança pelo arquivador. Eu também acredito que esta era a intenção dos criadores do GNU tar, pelo menos, deveria ter sido ;-)
mit

2
Descobri que a opção --remove-files remove o diretório que contém - pelo menos em algumas plataformas / em algumas versões - e no meu caso. Pode ser que, no seu caso, o diretório restante não esteja completamente vazio devido a alguns arquivos serem modificados após serem tarados.
Isync

@isync Parece que estou experimentando --remove-files excluindo diretórios no Ubuntu 14.04. Exceto no meu caso, não quero. Haha
Bradley Odell

Respostas:


12

Está faltando a parte que diz que a --remove-filesopção remove os arquivos depois de adicioná-los ao arquivo morto.

Você pode seguir a operação de arquivamento e remoção de arquivos com um comando como,

encontre / caminho / para / seja / arquivado / -thth -type d -empty -exec rmdir {} \;


Atualização: Você pode estar interessado em ler esta breve discussão sobre o Debian,
Bug 424692: --remove-files reclama que os diretórios "mudaram à medida que o lemos" .


Talvez seja realmente: -caltera o diretório antes de tariniciar seu trabalho (e meio que não retorna até que seja feito)? Eu acho que ele teria excluído subdiretórios, se eles estivessem incluídos no arquivo (mas eu não testei isso).
Arjan

@ Arjan, eu não acho que ' c'tenha algo a ver com isso; 'remove-files'intencionalmente não remove diretórios.
Nik

Ah, acho a breve explicação "remover arquivos depois de adicioná-los ao arquivo" das manpáginas não muito claras, mas presumo que você esteja certo. Ainda assim, eu não esperaria o diretório mencionado para -cser removido, mesmo se tar fez diretórios remove também. (Para mim, seria como remover o diretório atual, incluindo o próprio arquivo quando não estiver usando -c...?) Mas se -remove-filessempre deixar os diretórios no lugar, certamente estou apenas complicando as coisas aqui. ;-)
Arjan

3
--remove-filesbug foi corrigido tar-1.19.
x-yuri

19

Como a --remove-filesopção remove apenas arquivos , você pode tentar

tar -cvf files.tar my_directory && rm -R my_directory

para que o diretório seja removido apenas se tarretornar um status de saída 0


9
exceto que você deve verificar o status de saída do tar antes de fazer o rm! caso contrário você pode ficar com nenhuma arquivo tar e nenhum arquivo ...
Kim

1
Ao usar diretórios de um nível, acredito que uma opção mais segura seria usar 'rmdir' em vez de 'rm', pois isso removeria apenas um diretório vazio. [Veja edições da pergunta]
Nicholas

Mas rmdirapenas remove diretórios vazios . A idéia era para remover o diretório e os arquivos nele (desde que tarseja bem sucedido)
pavium

--remove-filesbug foi corrigido tar-1.19.
x-yuri

&& executará apenas o seguinte comando, se o comando anterior sair de 0 (êxito). Se sair> 0, o seguinte comando não será executado. Você também pode reverter isso com || - execute apenas se o primeiro comando falhar. Uma boa maneira de fazer uma verificação terrível de conteúdo reinicia essa.
Kirrus 15/10

6

Você tentou colocar a diretiva --remove-files após o nome do arquivo? Funciona para mim.

tar -cvf files.tar --remove-files my_directory

1
É mais provável que o comportamento do alcatrão tenha mudado desde que essa pergunta foi feita. Para mim, não há diferença em colocar --remove-filesantes ou depois my_directory; nos dois casos, o diretório é removido.
Redburn

5
--remove-filesbug foi corrigido tar-1.19.
x-yuri

1
source={directory argument}

por exemplo

source={FULL ABSOLUTE PATH}/my_directory

 

parent={parent directory of argument}

por exemplo

parent={ABSOLUTE PATH of 'my_directory'/

 

logFile={path to a run log that captures status messages}

Então você pode executar algo como:

cd ${parent}

tar cvf Tar_File.`date%Y%M%D_%H%M%S` ${source}

if [ $? != 0 ]

then

 echo "Backup FAILED for ${source} at `date` >> ${logFile}

else

 echo "Backup SUCCESS for ${source} at `date` >> ${logFile}

 rm -rf ${source}

fi

1

Provavelmente foi um bug.

Também a palavra "arquivo" é ambígua neste caso. Mas como esta é uma opção de linha de comando, seria de esperar também diretórios, porque no unix / lnux tudo é um arquivo, também um diretório. (A outra interpretação também é válida, é claro, mas não faz sentido manter diretórios nesse caso. Eu consideraria um comportamento inesperado e confuso.)

Mas eu descobri que no gnu tar, em algumas distribuições, o gnu tar na verdade remove a árvore de diretórios. Outra indicação de que manter a árvore era um bug. Ou, pelo menos, alguma solução alternativa até corrigi-lo.

Isto é o que eu tentei em um console do ubuntu 10.04:

mit: / var / tmp $ mkdir árvore1                                                                                               
mit: / var / tmp $ mkdir árvore1 / sub1                                                                                          
mit: / var / tmp $> árvore1 / sub1 / arquivo1                                                                                        

mit: / var / tmp $ ls -la                                                                                                    
drwxrwxrwt 4 raiz do root 4096 2011-11-14 15:40.                                                                              
drwxr-xr-x 16 root root 4096 2011-02-25 03:15 ..
drwxr-xr-x 3 mit mit 4096 2011-11-14 15:40 tree1

mit: / var / tmp $ tar -czf árvore1.tar.gz árvore1 / --remove-files

# COMO VOCÊ PODE VER A ÁRVORE FOI AGORA:

mit: / var / tmp $ ls -la
drwxrwxrwt 3 raiz do root 4096 2011-11-14 15:41.
drwxr-xr-x 16 root root 4096 2011-02-25 03:15 ..
-rw-r - r-- 1 mit mit 159 2011-11-14 15:41 tree1.tar.gz                                                                   


mit: / var / tmp $ tar --version                                                                                             
alcatrão (alcatrão GNU) 1,22                                                                                                           
Direitos autorais © 2009 Free Software Foundation, Inc.

Se você quiser vê-lo em sua máquina, cole-o em um console por sua conta e risco:

tar --version                                                                                             
cd / var / tmp
mkdir -p tree1 / sub1                                                                                          
> árvore1 / sub1 / arquivo1                                                                                        
tar -czf tree1.tar.gz tree1 / --remove-files
ls -la
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.