Supongamos que tengo la siguiente tubería:
a | b | c | d
¿Cómo puedo esperar para completar c(o b) en sho bash? Esto significa que la secuencia de comandos dpuede iniciarse en cualquier momento (y no es necesario esperar), pero requiere que la salida completa de cfuncione correctamente.
El caso de uso es difftoolpara gitcomparar imágenes. Es invocado por gity necesita procesar su entrada (la a | b | cparte) y mostrar los resultados de la comparación (la dparte). La persona que llama eliminará la entrada que se requiere para ay b. Esto significa que antes de regresar del script, el proceso c(o b) debe finalizar. Por otro lado, no puedo esperar dporque esto significa que estoy esperando la entrada del usuario.
Sé que puedo escribir los resultados cen un archivo temporal, o tal vez usar un FIFO en bash. (Sin embargo, no estoy seguro si el FIFO ayudará). ¿Es posible lograr esto sin archivos temporales sh?
EDITAR
Quizás sería suficiente si pudiera encontrar la identificación del proceso del c(o b) proceso de manera confiable. Entonces, toda la tubería podría iniciarse de forma asincrónica, y podría esperar una ID de proceso. Algo en la línea de
wait $(a | b | { c & [print PID of c] ; } | d)
EDITAR ^ 2
He encontrado una solución, los comentarios (o soluciones aún mejores) son bienvenidos.

dcomenzar a procesarcla salida solo después de que sechaya completado? ¿No deseadcomenzar a procesar cada línea de salida tal como viene?des libre de comenzar cuando lo desee, perocdebe terminar antes de que pueda seguir adelante.dpuede comenzar cuando le gusta, ¿qué está esperando exactamente?dno utiliza la salida dec, parece que no tiene sentido formardparte de la tubería. Pero sidusa la entrada, entoncesddebe trabajar un poco en su entrada después de haberla leído todo para que su enfoque marque la diferencia.Respuestas:
La notificación se puede hacer, por ejemplo, mediante una señal a un PID que se ha pasado en una variable de entorno (
kill -USR1 $EXTPID) o creando un archivo (touch /path/to/file).Otra idea:
Ejecuta el siguiente proceso (el que puede comenzar a esperar) desde la tubería:
o
fuente
notifypodría ejecutarse antes de configurar la trampa de señal. ¿Cómo puedo asegurarme de no perder esa señal?trapse haya definido.{ c; bg; }o{ c; exit 0; }no parece funcionar.Si entiendo su pregunta correctamente, esto debería funcionar:
(El truco de fd 3 se debe a que algunos (la mayoría) shells redirigen stdin a / dev / null with
&).fuente
En bash, puedes usar una sustitución de proceso . El comando en la sustitución del proceso se ejecuta de forma asincrónica, no se espera.
fuente
bashsolo, ¿no esshcompatible?Esto es lo que he encontrado por prueba y error, con la ayuda de la aportación de Hauke:
Equivalentemente:
(Este último es más explícito, porque de
{}todos modos se ejecutará en una subshell si está dentro de una tubería).Algunas otras señales (incluidas
QUIT,TERMyUSR1) también funcionan, sin embargo, en este caso, la descripción de la señal se muestra en el terminal.Me pregunto si esta es la intención original de la
PIPEseñal. De acuerdo con el manual :Esto significa que cuando envío artificialmente una señal de tubería a la subshell, finaliza en silencio, dejando solo al consumidor final (
d).Esto funciona en ambos
shybash.fuente
Puede usar el
spongeprograma desde el paquete "moreutils":a | b | c | sponge | dla esponja será para el final de
cla salida antes de conectarlad. Espero que eso sea lo que querías.fuente
Solo puedes hacer:
Entonces, cuando
dtermina,catabsorberá el resto decla producción hasta que termine.Okay. Después de los comentarios, creo que la respuesta es comenzar directamente
den segundo plano.Hacer:
o use la solución de Stephane Chazelas si hay problemas con la
dlectura de stdin .fuente
ctermina antesdy tengo que esperar hasta quectermine, pero no me importad.ctermine ydsiga funcionando? Matard?dtiene una GUI y puede ejecutarse hasta que el usuario la cierre.a,bycterminan su trabajo, cierran stdout y salen; y solodsigue funcionando. ¿Quieres enviardal fondo cuandoctermine? ¿Es asi?ddebe enviarse a un segundo plano una vez quecfinalice.