Um comando tar normal
tar cvf foo.tar ./foo >foo.out 2>foo.err
possui três fluxos de E / S de saída
- arquivar dados no foo.tar
- lista de nomes de arquivos para STDOUT (redirecionada para foo.out)
- mensagens de erro para STDERR (redirecionadas para foo.err)
Posso inspecionar o foo.err em busca de mensagens de erro sem precisar ler a lista de nomes de arquivos.
se eu quiser fazer alguma coisa com os dados do arquivo (canalizá-lo através do netcat ou de um programa de compactação especial), posso usar a -f -
opção tar
tar cvf - ./foo 2>foo.err | squish > foo.tar.S
Mas agora minha lista de nomes de arquivos está misturada às minhas mensagens de erro, porque a -v
saída do tar obviamente não pode ir para STDOUT (é para onde os dados do arquivo fluem), então o tar habilmente escreve isso no STDERR.
Usando o shell Korn, existe uma maneira de construir um comando que canaliza o fluxo de archive para outro comando, mas ainda captura a -v
saída separadamente de qualquer mensagem de erro.
tee
? Parece um caso de uso bastante válido para isso.Respostas:
Se o seu sistema suportar
/dev/fd/n
:Quais com as implementações da AT&T de
ksh
(oubash
ouzsh
) você pode escrever usando a substituição de processo :Isso está fazendo exatamente a mesma coisa, exceto que desta vez, o shell decide qual descritor de arquivo usar em vez de
3
(normalmente acima de 9). Outra diferença é que desta vez, você obtém o status de saída emtar
vez desquish
. Em sistemas que não suportam/dev/fd/n
, alguns shells podem recorrer a pipes nomeados para esse recurso.Se seu sistema não suportar
/dev/fd/n
ou seu shell não puder usar pipes nomeados para sua substituição de processo, é aí que você terá que lidar com pipes nomeados manualmente .fonte
Você precisa usar um pipe nomeado para isso.
Primeiro, crie um na pasta:
Em seguida, use esse comando:
Observe: a
cat
parte-agora também pode sergzip
ou seja o que for, que pode ler de um tubo:Explicação:
O resultado é enviado para o tubo de nome (
foo.pipe
), onde outro proccess (cat
,gzip
,netcat
) lê. Portanto, você não perde os canais stdout / stderr para obter informações.fonte
umask 077
(ou usar um diretório temporário privado) para impedir que outros processos sejam lidos ou gravados nele (em muitos sistemas, pipes nomeados, como outros arquivos são criados legíveis pelo mundo por padrão), 2) você precisa garantir o pipe nomeado é usado apenas por cada instância do seu script (novamente, um diretório temporário privado único ajuda) 3) Isso significa que você precisa fazer a limpeza posteriormente ou se for interrompido.p="/tmp/pipe$$"; mkfifo "$p"; (read na; cmd[s]...) <>"$p" & (echo;rm "$p"; cmd[s]...) >"$p"
A
--index-file
opção do GNU tar funciona bem:fonte