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
foomuestre antesbar, despuésbaro incluso después de la solicitud, según el momento. Agregue un poco de retraso para obtener un tiempo constante:baraparece inmediatamente, luego defooun 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, elechocomando termina sin bloqueo.echo bar.sleep 2.sleep 1.sleep 1regresa en el subproceso. El subproceso procede a ejecutarsecat.catcopia su entrada a su salida (que se muestra en la pantalla) y regresa.sleep 2regresa. 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,catse 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
bashimprimir 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 imprimirfooy una nueva línea.fuente