Quero dizer que, é claro, posso apenas codificá-lo e verificá-lo, mas não tenho certeza se é um comportamento definido ou se estou explorando recursos nos quais não devo confiar.
Isso depende do shell e não está documentado no AFAICS. No kshe bash, no primeiro caso, foocompartilhará o mesmo padrão que bar. Eles vão lutar pela produção de echo.
Você vê evidências de que pastelê todos os outros blocos de texto da seqsaída enquanto trlê os outros.
Com zsh, obtém o stdin externo (a menos que seja um terminal e o shell não seja interativo, caso em que é redirecionado /dev/null). ksh(onde se originou) zshe bashsão os únicos reservatórios semelhantes a Bourne com suporte para a substituição do processo AFAIK.
Em echo "bla" | bar < <(foo), observe que baro stdin será o tubo alimentado pela saída de foo. Esse é um comportamento bem definido. Nesse caso, parece que foostdin é o tubo alimentado por echotodos ksh, zshe bash.
Se você deseja ter um comportamento consistente em todas as três conchas e ser à prova de futuro, pois o comportamento pode mudar porque não está documentado, eu escreveria:
echo bla |{ bar <(foo);}
Para ter certeza foo, o stdin também é o cachimbo de echo(não consigo ver por que você faria isso). Ou:
echo bla | bar <(foo </dev/null)
Para se certificar de fooque não ler a partir do tubo de echo. Ou:
{ echo bla | bar 3<&-<(foo <&3);}3<&0
Ter foostdin o stdin externo como nas versões atuais de zsh.
"Nesse caso, o stdin de foo é o tubo alimentado por eco em todos os ksh, zsh e bash". Você testou isso manualmente agora ou está documentado em algum lugar?
Etam1024
"No primeiro caso" na primeira linha se refere a `| foo | bar` ou `| bar <(foo) `?
Volker Siegel
4
echo "bla" | foo | bar: A saída de echo "bla"é redirecionada para foo, cuja saída é redirecionada bar.
echo "bla" | bar <(foo): Esse canaliza a saída de echo "bla"para bar. Mas baré executado com um argumento. O argumento é o caminho para o descritor de arquivo, para onde a saída de fooserá enviada. Esse argumento se comporta como um arquivo que contém a saída de foo. Então, isso não é o mesmo.
echo "bla" | bar < <(foo): Pode-se supor que a saída de echo "bla"deve ser enviada para bare toda a instrução é equivalente à primeira. Mas isso não está correto. O seguinte acontece: Como o redirecionamento de entrada <é realizado após o pipe ( |), ele o substitui . Portanto, echo "bla"não é canalizado para bar. Em vez disso, a saída de fooé redirecionada como entrada padrão para bar. Para limpar isso, consulte o seguinte comando e saída:
$ echo "bla"| cat <<(echo "foo")
foo
Como você vê, echo "bla"é substituído por echo "foo".
Agora veja este comando:
$ echo "bar"| cat <<(awk '{printf "%s and foo", $0}')
bar and foo
Assim, echo "bar"é canalizado para awk, que lê stdin e adiciona a string and fooà saída. Esta saída é canalizada para cat.
E minha pergunta é: "O fato de awkler" bar "é um comportamento definido?"
etam1024
Sim, ele é. cmd1 < <(cmd2)se comporta da mesma forma que cmd2 | cmd1.
caos
Ou cmd1 | cmd2 | cmd3é o mesmo quecmd1 | cmd3 < <(cmd2)
caos
3
Se fosse a Wikipedia, eu colocaria a tag "citation needed" em suas declarações :) O ponto principal da minha pergunta é que funciona como você diz, mas não consegui encontrar nenhuma documentação sobre isso.
echo "bla" | foo | bar
: A saída deecho "bla"
é redirecionada parafoo
, cuja saída é redirecionadabar
.echo "bla" | bar <(foo)
: Esse canaliza a saída deecho "bla"
parabar
. Masbar
é executado com um argumento. O argumento é o caminho para o descritor de arquivo, para onde a saída defoo
será enviada. Esse argumento se comporta como um arquivo que contém a saída defoo
. Então, isso não é o mesmo.echo "bla" | bar < <(foo)
: Pode-se supor que a saída deecho "bla"
deve ser enviada parabar
e toda a instrução é equivalente à primeira. Mas isso não está correto. O seguinte acontece: Como o redirecionamento de entrada<
é realizado após o pipe (|
), ele o substitui . Portanto,echo "bla"
não é canalizado para bar. Em vez disso, a saída defoo
é redirecionada como entrada padrão parabar
. Para limpar isso, consulte o seguinte comando e saída:Como você vê,
echo "bla"
é substituído porecho "foo"
.Agora veja este comando:
Assim,
echo "bar"
é canalizado paraawk
, que lê stdin e adiciona a stringand foo
à saída. Esta saída é canalizada paracat
.fonte
awk
ler" bar "é um comportamento definido?"cmd1 < <(cmd2)
se comporta da mesma forma quecmd2 | cmd1
.cmd1 | cmd2 | cmd3
é o mesmo quecmd1 | cmd3 < <(cmd2)