Faça tar do arquivo / dev / stdin

5

O que eu estou procurando é uma maneira de passar dados arbitrários através de STDIN, e tê-lo como se fosse um arquivo normal.

Eu tentei isso

$ echo test | tar -cf test.tar /dev/stdin

e isso me dá um arquivo test.tar com o conteúdo dev/stdin . O arquivo stdin é um link para /proc/self/fd/0 .

O que eu quero, em vez disso, é que dev/stdin dentro do arquivo TAR seja um arquivo regular com o texto test dentro. Uma coisa semelhante acontece com:

$ tar -cf test.tar <(echo test)

mas os nomes são diferentes.

Isso é factível?

    
por Daffy 05.08.2018 / 03:52

3 respostas

4

Eu não acho que você pode fazer o que quiser aqui. O problema com sua abordagem é que tar lida em arquivos e árvores de diretórios, o que você não está fornecendo com comandos como este:

$ echo test | tar -cf test.tar /dev/sdtin

Mesmo quando você tenta "agrupar" suas strings em arquivos temporários usando subshells como este:

$ tar -cf test.tar <(echo test)

Você pode ver que seu conteúdo ainda está sendo usado usando esses descritores de arquivos temporários:

$ tar tvf test.tar
lr-x------ vagrant/vagrant   0 2018-08-04 23:52 dev/fd/63 -> pipe:[102734]

Se você pretende apenas compactar strings, você precisa colocá-las em um contexto de arquivo. Então você precisa fazer algo assim:

$ echo "test" > somefile && tar -cf /tmp/test.tar somefile

Você pode ver o arquivo presente dentro do arquivo TAR:

$ tar tvf /tmp/test.tar
-rw-rw-r-- vagrant/vagrant   5 2018-08-05 00:00 somefile

Replicando dados usando tar

A maioria dos que já trabalham com o Unix há vários anos provavelmente já viu esse padrão:

$ (cd /; tar cf - .)|(cd /mnt/newroot; tar pxvf -)

Eu costumava usar isso o tempo todo para replicar dados de um local para outro. Você pode usar isso também no SSH. Outros métodos são discutidos neste documento sobre as perguntas e respostas intitulado: clone árvore de diretórios raiz usando o busybox .

Backup /

Existe também este método se você pretende fazer backup do disco rígido principal:

$ sudo tar -cvpzf backup.tar.gz --exclude=/backup.tar.gz --one-file-system /

Referências

por 05.08.2018 / 06:02
2

Você pode criar um arquivo tar como um fluxo se souber o tamanho final do que deseja transmitir (em bytes). É, então, uma questão de criar o cabeçalho inicial de 512 bytes antes do fluxo de dados e um preenchimento posterior após ele. Embora isso dependa da variante exata do arquivo tar , uma vez que existem alguns formatos de arquivo diferentes. As etapas a seguir podem funcionar para você:

  1. crie um arquivo com o mesmo tamanho que o fluxo de dados

    $ dd if=/dev/zero of=mystream bs=1 count=0 seek=$SIZE

    Observe que mystream agora é um arquivo "hole" que na verdade não ocupa espaço em disco, embora pareça ter o mesmo tamanho, $ SIZE, que o fluxo de dados.

  2. use tar para criar um cabeçalho para um arquivo chamado mystream desse tamanho

    $ tar cf - mystream | head -c 512 > header

    Observe que tar desejará criar um arquivo sem furo, portanto, é importante descartar tudo, exceto os primeiros 512 bytes. Em seguida, remova o arquivo do furo, para evitar que ele seja copiado acidentalmente.

    $ rm mystream

  3. crie um trailer de preenchimento para preencher um número de 512 blocos.

    $ head -c $((echo "scale=0; 512 - $SIZE % 512" | bc )) > trailer

  4. faça o fluxo de alcatrão de $ STREAM (de tamanho $ SIZE) com cabeçalho e trailer

    $ cat header $STREAM trailer

    Note que você provavelmente desejaria transmitir isso para algo diferente de stdout.

por 05.08.2018 / 06:59
2

Com zsh , você pode usar a forma =(...) de substituição de processo que usa um arquivo temporário em vez de um canal. Com a opção tar do GNU --transform , você pode alterar o nome do membro do arquivo:

tar --transform='s/.*/test-file/' -zcf file.tar.gz =(echo test)

Criaria um file.tar.gz com um test-file membro com permissões 0600 e conteúdo test\n .

Com bash (ou zsh ), você poderia fazer:

tar --transform='s/.*/test-file/' -zchf file.tar.gz /dev/stdin <<< "$(echo test)"

Aqui, as strings também usam arquivos temporários nesses shells. Note, entretanto, que a substituição de comandos retira todo caractere de nova linha e adiciona um de volta e em bash removeria bytes NUL.

    
por 05.08.2018 / 09:05