Terminar un script de shell bash ejecutándose en segundo plano

16

A menudo uso bashscripts de shell para ejecutar comandos simples para muchos archivos diferentes. Por ejemplo, supongamos que tengo el siguiente bashscript, llamado script.sh, que ejecuta el comando / programa fooen tres archivos de texto "a.txt", "b.txt", "c.txt":

#!/bin/bash

for strname in "a" "b" "c"
do
foo $strname".txt"
done

Además, suponga que foo $strname".txt"es lento, por lo que la ejecución del script llevará mucho tiempo (horas o días, por ejemplo). Debido a esto, me gustaría usarlo nohuppara que la ejecución continúe incluso si el terminal está cerrado o desconectado. También me gustaría que el script pase inmediatamente al fondo, por lo que utilizaré el &operador. Por lo tanto, usaré el siguiente comando para llamar script.sh:

nohup bash script.sh &

Esto funciona bien para ejecutar el script en segundo plano y sin colgar, pero ahora suponga que me gustaría terminar la ejecución en algún momento por algún motivo. ¿Cómo puedo hacer esto?

El problema que he encontrado es que, al mirar top, solo veo el foocorrespondiente a "a.txt". Puedo terminar esa foollamada, pero luego se llama fooal correspondiente "b.txt"y luego tengo que terminar esa, y así sucesivamente. ¡Para decenas o cientos de archivos de texto especificados en el forbucle, se vuelve difícil terminar cada foouno por uno! Entonces, de alguna manera, necesito terminar el script de shell en , no las llamadas particulares emitidas desde el script de shell.

Cuando escribo el comando

ps -u myusername

donde myusernameestá mi nombre de usuario, obtengo una lista de los procesos que estoy ejecutando. Pero veo dos ID de proceso diferentes llamadas bash. ¿Cómo sé cuál de estos procesos, si corresponde, corresponde a mi llamada original nohup bash script.sh &?

Andrés
fuente
@ Andrew, ¿Muestran ambos procesos el nohup mencionado en el comando? ... alternativamente, puede probar ps -aWu Andrew y verificar si encuentra una única entrada larga con nohup ... ¿ayuda?
Nitin
2
Como comentario, su cita es una locura. for s in a b c; do foo "$s".txt; done
tripleee
1
@NSD: No, nohuphabrá desaparecido cuando aparezca una lista de procesos para ver el trabajo que comenzó. Puede mirar la columna "amabilidad" en la pssalida, pero las respuestas aquí son más útiles.
tripleee

Respuestas:

9

Por defecto, psno mostrará los parámetros con los que se llamó al programa. Las opciones -fy -lambas mostrarán la llamada completa.

ps -fu username

dará como resultado una salida similar a:

username 23464 66.7  0.0  11400   628 pts/5    R    15:28   1:40 bash script.sh
j883376
fuente
2
Eso es moderadamente útil, pero no desambigua múltiples procesos con los mismos argumentos.
tripleee
11

Tienes unas cuantas opciones. Como su proceso se está ejecutando en segundo plano, puede usarlo jobspara encontrarlo:

nohup bash script.sh &
...
jobs
[1]+ Running    nohup bash script.sh &
kill %1
jobs
[1]+ Terminated nohup bash script.sh &

También puede usar pkillpara buscar en la tabla de proceso una coincidencia de línea de comando; verbigracia:

pkill -f script.sh
JRFerguson
fuente
1

La pssalida (con, por ejemplo, ps aux) incluye el ID del proceso principal. Matar al padre bash, y sus hijos, también, serán terminados.

Para una visualización ASCII del árbol de procesos, intente pstree -pejecutar algunos procesos en segundo plano.

tripleee
fuente