Digamos que tenemos un script bash así:
echo "x" &
echo "y" &
echo "z" &
.....
echo "Z" &
wait
¿hay una manera de recoger los códigos de salida de los subprocesos conchas / sub? Buscando manera de hacer esto y no puede encontrar nada. Necesito funcionar estos subniveles en paralelo, de lo contrario sí, esto sería más fácil.
Busco a una genérica solución (no tengo un número desconocido / dinámica de subprocesos para ejecutar en paralelo).
bash
shell-script
shell
subshell
Alexander Mills
fuente
fuente
Respuestas:
La respuesta de Alexander Mills que usa handleJobs me dio un excelente punto de partida, pero también me dio este error
Que puede ser un problema de condición de carrera bash
En su lugar lo hice tienda pid de cada niño y espera y recibe el código de salida para cada niño en particular. Encuentro este limpiador en términos de subprocesos que generan subprocesos en funciones y evitan el riesgo de esperar un proceso principal donde pretendía esperar al hijo. Su más claro lo que sucede porque no es el uso de la trampa.
fuente
for job in "${childen[@]}"; do
debería serfor job in "${1}"; do
, para mayor claridadchildren_pids+=("$!")
realmente está capturando el pid deseado para el sub shell.Úselo
wait
con un PID, que :Deberá guardar el PID de cada proceso a medida que avanza:
También puede habilitar el control del trabajo en la secuencia de comandos con
set -m
una%n
especificación de trabajo y usarla , pero es casi seguro que no quiera hacerlo: el control del trabajo tiene muchos otros efectos secundarios .wait
devolverá el mismo código que el proceso finalizado. Puede usarwait $X
en cualquier punto posterior (razonable) para acceder al código final$?
o simplemente usarlo como verdadero / falso:wait
se detendrá hasta que el comando se complete si aún no lo ha hecho.Si se quiere evitar estancamiento de esa manera, se puede establecer un
trap
sobreSIGCHLD
, contar el número de terminaciones, y manejar todos loswait
s de una sola vez, cuando todos ellos han terminado. Probablemente pueda salirse con el usowait
solo casi todo el tiempo.fuente
wait $X
en cualquier punto posterior (razonable).Si tuviera una buena manera de identificar los comandos, podría imprimir su código de salida en un archivo tmp y luego acceder al archivo específico que le interesa:
No olvides eliminar los archivos tmp.
fuente
Use a
compound command
- ponga la declaración entre paréntesis:dará la salida
Una forma realmente diferente de ejecutar varios comandos en paralelo es usando GNU Parallel . Haga una lista de comandos para ejecutar y póngalos en el archivo
list
:Ejecute todos los comandos en paralelo y recopile los códigos de salida en el archivo
job.log
:y la salida es:
fuente
PIPESTATUS
es algo que debe salir. Estoseq 10 | gzip -c > seq.gz ; echo ${PIPESTATUS[@]}
regresa0 0
(código de salida del primer y último comando).Este es el script genérico que estás buscando. El único inconveniente es que sus comandos están entre comillas, lo que significa que el resaltado de sintaxis a través de su IDE realmente no funcionará. De lo contrario, he probado algunas de las otras respuestas y esta es la mejor. Esta respuesta incorpora la idea de usar
wait <pid>
dada por @Michael pero va un paso más allá al usar eltrap
comando que parece funcionar mejor.gracias a @michael homer por llevarme por el buen camino, pero usar el
trap
comando es el mejor enfoque AFAICT.fuente
Otra variación de la respuesta de @rolf:
Otra forma de guardar el estado de salida sería algo así como
y luego tener cada script
Esto le proporciona un nombre único para cada archivo de estado, incluido el nombre del script que lo creó y su ID de proceso (en caso de que se esté ejecutando más de una instancia del mismo script) que puede guardar como referencia más adelante y ponerlos todos en el mismo lugar para que pueda eliminar todo el subdirectorio cuando haya terminado.
Incluso puede guardar más de un estado de cada script haciendo algo como
que crea el archivo como antes, pero le agrega una cadena aleatoria única.
O simplemente puede agregar más información de estado al mismo archivo.
fuente
script3
se ejecutará sólo siscript1
yscript2
tienen éxito yscript1
yscript2
serán ejecutadas en paralelo:fuente