Por que você não pode usar o / dev / stderr como um pipeline
O problema não está com paste
e nem com /dev/stdin
. Está com /dev/stderr
.
Todos os comandos são criados com um descritor de entrada aberto (0: entrada padrão) e duas saídas (1: saída padrão e 2: erro padrão). Geralmente, eles podem ser acessados com os nomes /dev/stdin
, /dev/stdout
e /dev/stderr
, mas veja Como portáteis são / dev / stdin, / dev / stdout e / dev / stderr? . Muitos comandos, incluindo paste
, também interpretarão o nome do arquivo -
para significar STDIN.
Quando você executa bb
sozinho, tanto STDOUT quanto STDERR são o console, onde a saída do comando geralmente aparece. As linhas passam por diferentes descritores (como mostrado pelo seu annotate-output
), mas acabam no mesmo lugar.
Quando você adiciona um |
e um segundo comando, fazendo um pipeline ...
bb | paste /dev/stdin /dev/stderr
o |
diz ao shell para conectar a saída de bb
à entrada de paste
. paste
primeiro tenta ler a partir de /dev/stdin
, que (via alguns symlinks) resolve seu próprio descritor de entrada padrão (que o shell acabou de conectar) para que a linha 1
apareça.
Mas o shell / pipeline não faz nada para STDERR. bb
ainda envia isso ( e1
e2
etc.) para o console. Enquanto isso, paste
tenta ler o mesmo console, que trava (até que você digite algo).
Seu link Por que não consigo read / dev / stdout com um editor de texto? ainda é relevante aqui porque essas mesmas restrições se aplicam a /dev/stderr
.
Como fazer um segundo pipeline
Você tem um comando que produz saída padrão e erro padrão e deseja paste
dessas duas linhas próximas umas das outras. Isso significa dois canais simultâneos, um para cada coluna. O pipeline de shell ... | ...
fornece um desses, e você precisará criar o segundo você mesmo e redirecionar o STDERR para ele usando 2>filename
.
mkfifo RHS
bb 2>RHS | paste /dev/stdin RHS
Se isso for para uso em um script, você pode preferir fazer o FIFO em um diretório temporário e removê-lo após o uso.