Como ler de stdin na substituição do processo? [duplicado]

3

Eu gostaria de enviar stdout para vários comandos , mas não sei como ler entrada padrão dentro da substituição do processo?

Minhas tentativas:

$ echo foo >(cat /dev/stdin) >(cat /dev/stdin)
foo /dev/fd/63 /dev/fd/62

$ echo foo >(cat -) >(cat -)
foo /dev/fd/63 /dev/fd/62

$ echo foo >(cat <&3) >(cat <&3) 3<&0
foo /dev/fd/63 /dev/fd/62
-bash: 3: Bad file descriptor
-bash: 3: Bad file descriptor

Versão alternativa do mesmo problema:

$ cat file | tee &>/dev/null >(cmd1 /dev/stdin) >(cmd2 /dev/stdin)

Qual é o jeito certo de fazer isso?

    
por kenorb 06.12.2015 / 20:21

1 resposta

3

Isto lê de stdin:

echo foo | tee >(read line </dev/stdin; echo "internal $line")

Você deve ter em mente que uma substituição de processo atua "como" um arquivo.
Pode ser usado onde um arquivo é esperado. O comando tee espera gravar em um arquivo.
Nesse comando estamos sendo específicos sobre o dispositivo para ler com: / dev / stdin. Nesse exemplo simples, o / dev / stdin pode ser removido e isso também funcionará:

echo foo | tee >(read line; echo "internal $line")

Se eu estiver entendendo sua necessidade corretamente, isso funcionará:

$ echo foo | tee >(read a </dev/stdin; echo "a is $a") \
>(read b </dev/stdin; echo "b is $b") \
>(read c </dev/stdin; echo "c is $c")
foo
a is foo
c is foo
b is foo

Eu omiti o prompt do PS2 para reduzir a confusão. Observe que cada substituição de processo substitui o uso de um arquivo (como: tee FILE FILE .... ).

A leitura não precisa ser o primeiro comando.

$ echo foo > >(echo "hello" | read b; read a </dev/stdin; echo "a is $a") 
a is foo

Note que aqui a "Substituição do processo" precisa de um redirecionamento.
essa é a razão dos dois > >( idiom.

Um eco simples, só imprimirá o número do fd usado (o nome do arquivo):

$ echo >(echo "hello")
/dev/fd/63
hello

É semelhante a:

$ echo "$file"
filename

Considerando que este é um idioma muito diferente:

$ echo > "$file"
    
por 06.12.2015 / 23:09