Quero exibir o conteúdo do arquivo tarredado sem extraí-lo, Cenário: Eu tenho a.tar e, dentro, existe um arquivo chamado ./x/y.txt
. Eu quero ver o conteúdo de y.txt
sem realmente extrair o a.tar
.
Quero exibir o conteúdo do arquivo tarredado sem extraí-lo, Cenário: Eu tenho a.tar e, dentro, existe um arquivo chamado ./x/y.txt
. Eu quero ver o conteúdo de y.txt
sem realmente extrair o a.tar
.
Respostas:
Provavelmente é uma opção específica do GNU, mas você pode usar -O
ou --to-stdout
extrair arquivos para a saída padrão
$ tar -axf file.tgz foo/bar -O
tar -axf file.tar.gz --wildcards --no-anchored '*read_this_file*' --O
quando, por exemplo, muitos arquivos coincidem *read_this_file*
. Tudo é impresso na mesma linha. Pelo man
, eu encontrei --to-command
. então Passar --to-command="echo '' && cat"
é um pouco de magia negra, mas funciona: D
$ tar -axf file.tgz foo/bar -O
Isso imprime o conteúdo de ./x/y.txt de a.tar para STDOUT.
tar xfO a.tar ./x/y.txt
Isso é simples como
less a.tar:./x/y.txt
Este truque de mágica funciona se você tiver lesspipe
instalado e se a variável env LESSOPEN
estiver definida como o | /usr/bin/lesspipe.sh %s
que é esperado se você tiver menos tubo instalado corretamente.
lesspipe.sh
provavelmente deve ser preferido.
Ah, mas essa é uma pergunta sobre o conteúdo de um arquivo dentro de um tar
arquivo. E, na verdade, em alguns casos, isso não é tão difícil. O problema é que um tar
arquivo é apenas um arquivo de fluxo bloqueado - cada arquivo no arquivo morto é encontrado depois do arquivo anterior e cada arquivo obtém um cabeçalho de metadados com base em um formato especificado .
Com base nesse formato, eu escrevi uma vez shitar
- que eram algumas linhas dd
e scripts de shell que podiam tar
criar um fluxo de dispositivos de bloco em tempo real. Baseado no mesmo, mais recentemente escrevi estas poucas linhas de código :
tar --no-recursion -c ./ |
{ printf \\0; tr -s \\0; } |
cut -d '' -f-2,13 |
tr '\0\n' '\n\t'
... para separar um tar
arquivo em tempo real e realizar transformações embutidas em seus arquivos de texto componentes. Lá, os cut
campos apontam para os campos 1,2,13 de uma linha de entrada delimitada por NUL . Tais coisas são fáceis quando o tar
arquivo contém apenas arquivos de texto porque tar
os delimitadores de registro (como podem ocorrer uma vez a cada 512 bytes) podem ser reduzidos a um único NUL por e retirados - sem exigir que você conte as ocorrências como faz.
tar
O formato do cabeçalho é assim:
field offset len
name 0 100
mode 100 8
uid 108 8
gid 116 8
size 124 12
mtime 136 12
chksum 148 8
typeflag 156 1
linkname 157 100
magic 257 6
version 263 2
uname 265 32
gname 297 32
devmajor 329 8
devminor 337 8
prefix 345 155
Entenda que existe uma inclinação acentuada entre a facilidade relativa de lidar tar
com operações simples com os aspectos muito mais complicados do formato de arquivo. Embora coisas simples - como agrupar um pequeno grupo de arquivos digitados de maneira homogênea ou até mesmo dividir um arquivo contendo apenas membros cujos tipos você possa prever - possam ser facilmente executadas com alguns tubos de shell, manipular com segurança membros arbitrários de arquivo não é um assunto trivial.
É especialmente difícil quando esses membros podem conter dados binários arbitrários - o que certamente impediria qualquer aplicação confiável de tr -s
- e essa dificuldade só aumenta quando arquivos de vários tipos diferentes de regulares e / ou charsets diferentes do seu nativo são usados e / ou o O arquivo original foi criado por uma implementação com idiossincrasias de aplicativo de formato com as quais você não está preparado para lidar. E isso toca apenas nos aspectos básicos e padronizados do tar
tipo de arquivo - adicione cabeçalhos estendidos e extensões de formato, arquivos esparsos e compactação e ... bem, boa sorte com eles.
De volta ao básico, no entanto, o tamanho padrão do registro para um tar
arquivo morto é de 20 blocos - ou 10240 bytes. Dado um arquivo bloqueado no tamanho de registro padrão e contendo apenas tipos de arquivo e ustar
cabeçalhos padrão , você deve pular de cabeçalho para cabeçalho de membro fazendo leituras de acordo com o size
campo de cabeçalho até encontrar um membro que corresponda ao de que você procura. Uma vez lá, leia em size
bytes o deslocamento começando no final do cabeçalho de membro do seu destino. E esse é o seu arquivo.
Pular os cabeçalhos não é muito fácil. Tipos diferentes terão ou não blocos de dados reais anexados que correspondem a size
. Por exemplo, diretórios e links não conterão esse bloco de dados, apenas uma descrição de cabeçalho e, portanto, você deve estar preparado para verificar o tipo de arquivo do cabeçalho atual antes de determinar exatamente se deve aplicar o size
campo à sua fórmula de ignorar ou não.
Além disso, os fatores de tamanho do registro - dependendo se os tamanhos dos membros do arquivo estão sincronizados ou não com o tamanho do registro padrão 10240 - , pode ou não haver um bloco 0 adicional anexado a cada um. E o tamanho do registro pode ser declarado no momento da criação do arquivo - e, portanto, pode nem ter 20 blocos, embora, por especificação, ele sempre deva ser bloqueado em unidades de 512 bytes:
tar
formato de intercâmbio; consulte a seção DESCRIÇÃO ESTENDIDA . O tamanho do bloco padrão para este formato para arquivos especiais de caracteres deve ser 10240 . As implementações devem oferecer suporte a todos os valores de tamanho de bloco menores ou iguais a 32256, múltiplos de 512 .Portanto, se você estava trabalhando com um tar
arquivo que pode conter arquivos que podem conter dados binários arbitrários, é necessário pular o arquivo algoritmicamente e de acordo com o tipo de arquivo. A especificação diz:
size
campo é o tamanho do arquivo em octetos.
typeflag
campo estiver definido para especificar um arquivo do tipo 1 (um link ) ou 2 (um link simbólico ) , o size
campo será especificado como zero.typeflag
campo estiver definido para especificar um arquivo do tipo 5 ( diretório ) , o size
campo deve ser interpretado conforme descrito na definição desse tipo de registro.typeflag
campo estiver definido como 3 ( arquivo especial de caracteres ) , 4 ( arquivo especial de bloco ) ou 6 ( FIFO ) , o significado do size
campo não será especificado por este volume do POSIX.1-2008 e nenhum registro lógico de dados deverá ser armazenado no meio.size
campo deve ser ignorado durante a leitura.typeflag
campo estiver definido com qualquer outro valor, o número de registros lógicos gravados após o cabeçalho deve ser , ignorando qualquer fração no resultado da divisão.( (
size
+ 511 ) / 512 )
... e, é claro, considerando também o tamanho individual de cada cabeçalho - que é um bloco adicional por membro. Portanto, você pode pular a leitura e a leitura de cabeçalho para cabeçalho até chegar a um que corresponda ao cabeçalho que você procura, e nesse momento seria necessário verificar se o registro atual apenas descreve um link para o seu arquivo ou para o arquivo real . Isso é especialmente relevante porque quando o mesmo arquivo é adicionado a um arquivo múltiplo várias vezes, muitos tar
s incluem apenas cabeçalhos de link porque os dados do arquivo real já podem ser encontrados em outras partes do arquivo.
Depois de verificar que você precisará aplicar seus cálculos ao chksum
campo e verificar se o arquivo que você pensa que possui é realmente o arquivo que você deseja. tar
's chksum
é bastante simples though-:
chksum
campo deve ser a representação IRV padrão ISO / IEC 646: 1991 do valor octal da soma simples de todos os octetos no registro lógico do cabeçalho. Cada octeto no cabeçalho deve ser tratado como um valor não assinado. Esses valores devem ser adicionados a um número inteiro não assinado, inicializado com zero, cuja precisão não é inferior a 17 bits. Ao calcular a soma de verificação, o chksum
campo é tratado como se fossem todos os caracteres <space> .Claro, você não iria realmente tem que fazer nada disso, porque tar
já pode fazer isso - isso é o que ele faz - e por isso você deve, provavelmente, apenas usá-lo para pesquisar o arquivo e extraia o arquivo para você. Ao fazer isso, não fará nada muito diferente do que você faria se soubesse o que era, exceto que provavelmente o fará melhor e mais rápido porque esse é o seu trabalho. E de qualquer maneira, por que você deveria?