tar para pipe, mas mantenha -v saída detalhada separada de STDERR

11

Um comando tar normal

tar cvf foo.tar ./foo >foo.out 2>foo.err

tem três fluxos de E / S de saída

  • arquivar dados em foo.tar
  • lista de nomes de arquivos para STDOUT (redirecionada para foo.out)
  • mensagens de erro para STDERR (redirecionadas para foo.err)

Eu posso então inspecionar foo.err para mensagens de erro sem ter que ler a lista de nomes de arquivos.

se eu quiser fazer algo com os dados do arquivo (canalizá-lo através do netcat ou um programa especial de compressão) eu posso usar a opção -f - do tarão assim

tar cvf - ./foo 2>foo.err | squish > foo.tar.S

Mas agora minha lista de nomes de arquivos está mesclada com minhas mensagens de erro porque a saída -v do tar obviamente não pode ir para STDOUT (é onde os dados do arquivo fluem), portanto, escreve habilmente para STDERR.

Usando o shell Korn, existe uma maneira de construir um comando que canalize o fluxo de archive para outro comando, mas ainda capture a saída -v separadamente de qualquer mensagem de erro.

    
por RedGrittyBrick 28.01.2015 / 13:24

3 respostas

8

Se o seu sistema suporta /dev/fd/n :

tar cvf /dev/fd/3 ./foo 3>&1 > foo.out 2>foo.err | squish > foo.tar.S

Qual das implementações AT & T de ksh (ou bash ou zsh ) você poderia escrever usando substituição de processo :

tar cvf >(squish > foo.tar.S) ./foo > foo.out 2>foo.err

Isso está fazendo exatamente a mesma coisa, exceto que, desta vez, o shell decide qual descritor de arquivo usar em vez de 3 (geralmente acima de 9). Outra diferença é que, desta vez, você obtém o status de saída de tar em vez de squish . Em sistemas que não suportam /dev/fd/n , alguns shells podem recorrer a pipes nomeados para esse recurso.

Se o seu sistema não suporta /dev/fd/n ou o seu shell não pode usar pipes nomeados para sua substituição de processos, é aí que você teria que lidar com pipes nomeados manualmente .

    
por 28.01.2015 / 13:39
5

Você tem que usar um pipe nomeado para isso.

Primeiro, crie um na pasta:

mkfifo foo.pipe

Em seguida, use esse comando:

tar cvf foo.pipe ./foo >foo.out 2>foo.err & cat foo.pipe >foo.tar

Aviso: o cat -part, agora também pode ser gzip ou qualquer outro, que possa ler de um canal:

tar cvf foo.pipe ./foo >foo.out 2>foo.err & gzip -c foo.pipe >foo.tar

Explicação:

A saída é gravada no canal de nome ( foo.pipe ), onde outro processo ( cat , gzip , netcat ) é lido. Então você não perde os canais stdout / stderr para obter informações.

    
por 28.01.2015 / 13:41
4
--index-file option funciona bem:

tar cvf - ./foo 2>foo.err --index-file=foo.out | squish > foo.tar.S
    
por 03.02.2016 / 17:06

Tags