El script de shell espera el comando en segundo plano

Estoy escribiendo un script, pero hay algo que necesito y no puedo encontrar la manera de hacerlo …

Necesito hacer un comando en segundo plano «command1 &» y luego en algún lugar del script necesito esperar a que termine antes de ejecutar command2. Básicamente , Necesito esto:

NOTA: ¡cada comando se ejecuta en un directorio específico! Al final del ciclo while, mi comando1 creó 4 directorios, donde en cada uno se ejecuta el proceso específico para que el total en ejecución son 4

 a=1 while [$a -lt 4 ] . command1 #Generates 1 Process a= `export $a +1` done #Wait until the 4 process end and then run the command2 . command2  

He visto algo sobre un wait comando con el número de proceso pid, pero eso no funcionó también.

Comentarios

  • ¿Usted controla command1? ¿Puede modificarlo para que devuelva los PID de los 4 procesos?
  • ¡Sí! ya lo tengo 🙂
  • He actualizado mi respuesta en consecuencia. Dime si coincide con tus expectativas.
  • Esta Q está relacionada con esta: unix.stackexchange.com/questions/100801/… . La única diferencia es que necesita obtener el PID de un proceso en segundo plano. Puede usar la variable $! para obtener esto, pasándola al comando wait como lo mostré allí. $! contiene el último PID en segundo plano, mientras que $$ contiene el último proceso ejecutado ' s PID .
  • Bien, ahora su secuencia de comandos no tiene ningún sentido. Hay errores de sintaxis y extrañeza por todas partes. ¿Podría mostrarnos el script actual ? ¿Por qué estás obteniendo comandos? ¿Por qué no simplemente ejecutarlos?

Responder

Puede usar el comando wait PID para esperar a que finalice un proceso.

También puede recuperar el PID del último comando con $!

En su caso, algo como esto funcionaría:

command1 & #run command1 in background PID=$! #catch the last PID, here from command1 command2 #run command2 while command1 is running in background wait $PID #wait for command1, in background, to end command3 #execute once command1 ended 

Después de su edición, como tiene varios PID y los conoce, puede hacerlo:

command1 & #run command1 in background PID1=xxxxx PID2=yyyyy PID3=xxyyy PID4=yyxxx command2 #run command2 while command1 is running in background wait $PID1 $PID2 $PID3 $PID4 #wait for the four processes of command1, in background, to end command3 #execute once command1 ended 

Comentarios

  • Después de su edición, si conoce el PID creado (xxxxx, yyyyy, xxyyy, yyxxx ), también puede usar wait, con la lista de PID para esperar (ver man). Si los ' no los conoce, tal vez pueda reunirlos en command1 (¿qué es command1? ¿Un script propio?)
  • Probablemente sea mejor asegurarse de que ' están agrupados correctamente en primer lugar. Vea mi respuesta para tener una idea de cómo se puede hacer.

Respuesta

La forma más limpia de hacer esto sería tener su comamnd1 devolver los PID de los procesos iniciados y usar wait en cada uno de ellos como lo sugiere @LaurentC «s respuesta .

Otro enfoque sería algo como esto:

## Create a log file logfile=$(mktemp) ## Run your command and have it print into the log file ## when it"s finsihed. command1 && echo 1 > $logfile & ## Wait for it. The [ ! -s $logfile ] is true while the file is ## empty. The -s means "check that the file is NOT empty" so ! -s ## means the opposite, check that the file IS empty. So, since ## the command above will print into the file as soon as it"s finished ## this loop will run as long as the previous command si runnning. while [ ! -s $logfile ]; do sleep 1; done ## continue command2 

Comentarios

  • lo siento, pero aún no funciona. ¡Mejoraré mi pregunta una vez más!

Responder

Si usa el siguiente método, es posible que no necesite una «espera para todos los procesos» especial después del ciclo while. El ciclo esperará el para completar antes de que vuelva al principio. Tenga cuidado como con cualquier consejo. Tenga en cuenta que lo único que hice fue agregar & wait $! al final de su command1.

a=1 while [$a -lt 4 ] . command1 & wait $! #Generates 1 Process a= `export $a +1` done 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *