criando um arquivo usando o tar incluindo todos os 'dotfiles', mas excluindo todos os subdiretórios e / ou estrutura de diretórios

17

Eu quero fazer backup de todos os 'dotfiles' (por exemplo, .zshrc ) em meu diretório inicial com tar , mas excluindo a estrutura de diretórios e todos os subdiretórios.

Eu tentei várias vezes com comandos diferentes, mas o melhor que consegui foi um arquivo que incluía os diretórios ocultos em $HOME também.

#!/bin/zsh
BACKUPFILE=dotfile_backup.tar.gz
tar --create --file=$HOME/$BACKUPFILE --auto-compress --no-recursion --exclude=. --exclude=.. --exclude=*/ --directory=$HOME .*

Eu também pensei em usar find e canalizar o resultado para o tar, mas sem sorte. Alguém sabe como conseguir essa tarefa aparentemente fácil?

PS: Na maior parte do tempo, quando estou usando tar para criar um arquivo, eu tenho que pensar em quadrinhos xkcd:

:)

    
por klingt.net 19.07.2013 / 16:29

4 respostas

13

Você pode usar este comando para fazer backup de todos os seus arquivos de ponto ( .<something> ) no diretório $HOME :

$ cd ~
$ find . -maxdepth 1 -type f -name ".*" -exec tar zcvf dotfiles.tar.gz {} +

regex usando apenas tar?

método # 1

Eu pesquisei bastante isso e cheguei vazio. O fator limitante seria que quando o tar está executando, é excluído, a barra final ( / ) que aparece com os diretórios não faz parte da equação quando o tar está executando sua correspondência de padrões.

Veja um exemplo:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*/'} .*
.qalculate/
.qt/
.qterm/
.qtoctave/
.RapidSVN
.RData
.Rhistory

Esta variante inclui uma exclusão de .*/ e você pode ver com a chave verbose ativada para tar, -v , que esses diretórios estão passando por essa exclusão.

método # 2

Pensei que talvez as opções --no-wildcards-match-slash ou --wildcards-match-slash relaxassem a ganância do .*/ , mas isso também não teve efeito.

Tirando a barra da exclusão, .* não era uma opção, já que isso diria a tar para excluir todos os dotfiles e dotdirectories:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --exclude={'.','..','.*'} .*
$

método # 3 (Feio!)

Portanto, a única alternativa que posso conceber é fornecer uma lista de arquivos para tar . Algo parecido com isto:

$ tar -v --create --file=do.tar.gz --auto-compress --no-recursion --wildcards-match-slash --exclude={'.','..','.*/'} $(ls -aF | grep -E "^\..*[^/]$")
.RapidSVN
.RData
.Rhistory

Esta abordagem tem problemas se o número de arquivos exceder a quantidade máxima de espaço para transmitir argumentos para um comando seria um problema evidente. A outra é que é feia e excessivamente complexa.

então o que aprendemos?

Parece não haver uma maneira simples e elegante de realizar isso usando tar & expressões regulares. De modo a comentar @Terdon, find ... | tar ... é realmente a maneira mais apropriada de fazer isso.

    
por 19.07.2013 / 16:53
4

Esse tipo de controle sobre arquivos correspondentes está bem fora da zona de conforto do tar. Suas regras para arquivos correspondentes são limitadas a simples correspondências sobre nomes.

find é unidirecional, mas como você tem zsh, você tem mais facilidade:

tar -cf "$HOME/$BACKUPFILE" --auto-compress .*(.)

Esse . entre parênteses no final da expressão curinga é um qualificador glob que diz "apenas correspondem a arquivos regulares".

Links simbólicos para arquivos regulares não são correspondidos. Se você mudar para .*(-.) , eles serão incluídos, mas o arquivo não será arquivado, a menos que também esteja incluído. Se você quiser substituir o link simbólico por seus destinos, faça com que .*(-.:A) - :A adicione a expansão do histórico modificador que resolve todos os links simbólicos para um caminho que não usa links simbólicos.

    
por 21.07.2013 / 01:59
3

Esta resposta é baseada em slm's, mas também mostrarei como incluir diretórios começando com .

Para zipar arquivos de ponto no diretório inicial:

$ cd
$ find . -maxdepth 1 -type f -name ".?*" -exec tar czfv dotfiles.tgz {} +

Para incluir diretórios:

$ find . -maxdepth 1 -name ".?*" -exec tar czfv dotfiles.tgz {} +

O ? é opcional no primeiro comando, mas não no segundo, caso contrário, find incluirá o diretório . (atual).

    
por 28.10.2013 / 04:06
1

e:

tar -C $HOME -cvzf dotfiles.tgz .
    
por 20.06.2016 / 21:36

Tags