Como fazer a globalização do tar funcionar com a opção 'alterar diretório'

8

Eu tenho a seguinte estrutura de diretórios:

base/
   files/
   archives/
   scripts/

Eu quero que um script seja executado a partir de scripts/ , comprima arquivos que correspondam a results.*.log em files/ em um arquivo tar compactado com gzip em archives/ .

Estou tentando o seguinte comando:

tar czfC ../archives/archive.tar.gz ../files results.*.log

Mas eu recebo

tar: results.*.log: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

Enquanto

tar czfC ../archives/archive.tar.gz ../files results.a.log

funciona como esperado. Também

tar czf ../archives/archive.tar.gz ../files/results.*.log

funciona do jeito que eu gostaria, exceto que adiciona o prefixo files/ ao arquivo e também emite um aviso:

tar: Removing leading '../' from member names

Portanto, minha conclusão é que tar globbing não funciona corretamente ao usar a opção -C . Algum conselho sobre como eu faço isso funcionar de uma maneira simples?

    
por Yuval 06.04.2013 / 16:23

6 respostas

3

Escreva de maneira mais portátil:

(cd ../files && tar cf - results.*.log) | 
  gzip -9 > ../archives/archive.tar.gz
    
por 06.04.2013 / 17:27
5

Não há "tar globbing", o globbing é feito pelo shell. E o shell não tem idéia de que tar -C somedir fará seu trabalho em somedir , todos os globs serão expandidos no diretório atual.

    
por 06.04.2013 / 16:26
1

Você pode deixar find fazer o globbing e omitir a opção 'alterar diretório' para tar removendo o prefixo files/ antes de criar o arquivo tar.

A opção --no-recursion para tar é opcional, pois nenhum diretório será arquivado.

cd base/scripts

# gnutar
# printf '%s
cd base/scripts

# gnutar
# printf '%s%pre%0' ../files/results.*.log |  # find alternative
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   gnutar --transform="s|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
gnutar -tf ../archives/archive.tar.gz | nl
gnutar -xzf ../archives/archive.tar.gz

# bsdtar
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   bsdtar -s "|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
bsdtar -tf ../archives/archive.tar.gz | nl
bsdtar -xzf ../archives/archive.tar.gz
0' ../files/results.*.log | # find alternative find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | gnutar --transform="s|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | gzip -9 > ../archives/archive.tar.gz gnutar -tf ../archives/archive.tar.gz | nl gnutar -xzf ../archives/archive.tar.gz # bsdtar find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | bsdtar -s "|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | gzip -9 > ../archives/archive.tar.gz bsdtar -tf ../archives/archive.tar.gz | nl bsdtar -xzf ../archives/archive.tar.gz
    
por 07.04.2013 / 11:42
0

Eu finalmente usei

tar czfC ../archives/archive.tar.gz ../files 'find ../files/results.*.log -printf "%f\n"'
    
por 06.04.2013 / 16:48
0

A maneira de fazer isso é escrever algo como o seguinte:

#!/bin/sh

cd ../files
tar zcf ../archives/archive.tar.gz results.*.log
cd ../scripts
    
por 06.04.2013 / 18:49
0

Não é o alcatrão que faz o globbing, é o shell. Primeiro você está dizendo ao shell para fazer globbing, então dizendo ao tar para mudar os diretórios. Como o tar está recebendo uma lista de nomes de arquivos em relação aos diretórios originais, isso não funciona.

A solução mais fácil é permitir que o shell altere o diretório. Interativamente:

cd ../files
tar czf ../archives/archive.tar.gz  results.*.log
cd -

Em um script:

(
  cd ../files &&
    tar czf ../archives/archive.tar.gz  results.*.log
)

ou

(
  cd ../files &&
    tar czf -  results.*.log
) >../archives/archive.tar.gz
    
por 08.04.2013 / 03:15

Tags