Mientras experimentaba con la redirección de salida y la sustitución de procesos, me topé con el siguiente comando y su salida resultante:
yo @ elem: ~ $ echo foo>> (gato); barra de eco bar yo @ elem: ~ $ foo
(Sí, esa nueva línea vacía al final es intencional).
Así que bash echo's bar, imprime mi mensaje habitual, echo's foo, echo's a newline, y deja mi cursor allí. Si presiono enter nuevamente, imprimirá mi mensaje en una nueva línea y dejará el cursor siguiendo (como se esperaba cuando alguien presiona enter en una línea de comando vacía).
Esperaba que escribiera foo en un descriptor de archivo, cat lo lee y echo's foo, la segunda barra de echo echo, y luego vuelve al símbolo del sistema. Pero claramente ese no es el caso.
¿Podría alguien explicarme qué está pasando?
bash
shell
process-substitution
concurrency
Stanley Yu
fuente
fuente
Respuestas:
Es posible que se
foo
muestre antesbar
, despuésbar
o incluso después de la solicitud, según el momento. Agregue un poco de retraso para obtener un tiempo constante:bar
aparece inmediatamente, luego defoo
un segundo, luego el siguiente mensaje después de otro segundo.Lo que sucede es que bash ejecuta sustituciones de proceso en segundo plano.
sleep 1; cat
, y configura una tubería hacia él.echo foo
. Como esto no llena el búfer de la tubería, elecho
comando termina sin bloqueo.echo bar
.sleep 2
.sleep 1
.sleep 1
regresa en el subproceso. El subproceso procede a ejecutarsecat
.cat
copia su entrada a su salida (que se muestra en la pantalla) y regresa.sleep 2
regresa. El proceso de shell principal termina de ejecutarse y puede ver el siguiente mensaje.fuente
No necesita la sustitución del proceso para obtener ese efecto. Prueba esto:
Obtendrá el mismo resultado (sin el
bar
; lo dejaré como ejercicio) y por la misma razón. En ambos casos,cat
se inicia como una tarea en segundo plano. En mi línea aquí, eso es explícito. En el caso de la sustitución de procesos, también es explícito, es un proceso separado adjunto a un descriptor de archivo de nombre, pero quizás no sea tan obvio.El proceso secundario no termina necesariamente antes de
bash
imprimir el siguiente mensaje. Y dado que su salida está almacenada, no genera nada hasta que finaliza. En ese momento, bash acaba de imprimir$
en stderr, y ahora el proceso de fondo se cierra después de imprimirfoo
y una nueva línea.fuente