¿Cuál de los fooy barlee "bla" de stdin y por qué?
Quiero decir que, por supuesto, solo puedo codificarlo y verificarlo, pero no estoy seguro de si es un comportamiento definido o si estoy explotando características en las que no debería confiar.
Eso depende del shell y no está documentado AFAICS. En kshy bash, en el primer caso, foocompartirá el mismo stdin que bar. Lucharán por la salida de echo.
Usted ve evidencia que pastelee cada dos bloques de texto de seqla salida de mientras trlee los otros.
Con zsh, obtiene el stdin externo (a menos que sea un terminal y el shell no sea interactivo, en cuyo caso se redirige /dev/null). ksh(donde se originó), zshy bashson los únicos proyectiles tipo Bourne con soporte para la sustitución de procesos AFAIK.
En echo "bla" | bar < <(foo), tenga en cuenta que barstdin será la tubería alimentada por la salida de foo. Ese es un comportamiento bien definido. En ese caso, parece que fooel stdin es la tubería alimentada echoen todos ksh, zshy bash.
Si desea tener un comportamiento constante en los tres shells y estar preparado para el futuro, ya que el comportamiento puede cambiar ya que no está documentado, lo escribiría:
echo bla |{ bar <(foo);}
Para estar seguro foo, el stdin también es el conducto de echo(aunque no puedo ver por qué querrías hacer eso). O:
echo bla | bar <(foo </dev/null)
Para asegurarse de fooque no se lee desde la tubería echo. O:
{ echo bla | bar 3<&-<(foo <&3);}3<&0
Tener fooel stdin el stdin externo como en las versiones actuales de zsh.
"En ese caso, el stdin de foo es la tubería alimentada por eco en todo ksh, zsh y bash". Has probado esto a mano hace un momento o ¿está documentado en algún lugar?
etam1024
¿"En el primer caso" en la primera línea se refiere a `| foo | bar` o `| bar <(foo) `?
Volker Siegel
4
echo "bla" | foo | bar: La salida de echo "bla"se redirige a foo, cuya salida se redirige a bar.
echo "bla" | bar <(foo): Ese canaliza la salida de echo "bla"a bar. Pero barse ejecuta con un argumento. El argumento es la ruta al descriptor de archivo, donde se enviará la salida de foo. Este argumento se comporta como un archivo que contiene la salida de foo. Entonces, eso no es lo mismo.
echo "bla" | bar < <(foo): Se puede suponer que la salida de se echo "bla"debe enviar a bary toda la declaración es equivalente a la primera. Pero eso no es correcto. Sucede lo siguiente: como la redirección de entrada <se realiza después de la tubería ( |), la sobrescribe . Por echo "bla"lo tanto, no se canaliza a la barra. En cambio, la salida de foose redirige como entrada estándar a bar. Para borrar esto, vea el siguiente comando y salida:
$ echo "bla"| cat <<(echo "foo")
foo
Como veis echo "bla"es reemplazado por echo "foo".
Ahora vea este comando:
$ echo "bar"| cat <<(awk '{printf "%s and foo", $0}')
bar and foo
Entonces echo "bar"se canaliza a awk, que lee stdin y agrega la cadena and fooa la salida. Esta salida se canaliza a cat.
Y mi pregunta es: "¿Es el hecho de que awklee" bar "un comportamiento definido?"
etam1024
Sí lo es. cmd1 < <(cmd2)se comporta igual que cmd2 | cmd1.
caos
O cmd1 | cmd2 | cmd3es lo mismo quecmd1 | cmd3 < <(cmd2)
caos
3
Si fuera wikipedia, pondría la etiqueta "cita requerida" en sus declaraciones :) El objetivo de mi pregunta es que funciona como usted dice, pero no pude encontrar ninguna documentación al respecto.
echo "bla" | foo | bar
: La salida deecho "bla"
se redirige afoo
, cuya salida se redirige abar
.echo "bla" | bar <(foo)
: Ese canaliza la salida deecho "bla"
abar
. Perobar
se ejecuta con un argumento. El argumento es la ruta al descriptor de archivo, donde se enviará la salida defoo
. Este argumento se comporta como un archivo que contiene la salida defoo
. Entonces, eso no es lo mismo.echo "bla" | bar < <(foo)
: Se puede suponer que la salida de seecho "bla"
debe enviar abar
y toda la declaración es equivalente a la primera. Pero eso no es correcto. Sucede lo siguiente: como la redirección de entrada<
se realiza después de la tubería (|
), la sobrescribe . Porecho "bla"
lo tanto, no se canaliza a la barra. En cambio, la salida defoo
se redirige como entrada estándar abar
. Para borrar esto, vea el siguiente comando y salida:Como veis
echo "bla"
es reemplazado porecho "foo"
.Ahora vea este comando:
Entonces
echo "bar"
se canaliza aawk
, que lee stdin y agrega la cadenaand foo
a la salida. Esta salida se canaliza acat
.fuente
awk
lee" bar "un comportamiento definido?"cmd1 < <(cmd2)
se comporta igual quecmd2 | cmd1
.cmd1 | cmd2 | cmd3
es lo mismo quecmd1 | cmd3 < <(cmd2)