¿Cómo detener un bash mientras el bucle se ejecuta en segundo plano?

23

Comencé un ciclo while de la siguiente manera:

while true; do {command}; sleep 180; done &

Note el &.

Pensé que cuando mataba la terminal, este ciclo se detendría. Pero todavía está yendo. Han pasado horas desde que maté la sesión terminal.

¿Cómo detengo esto mientras bucle?

Saqib Ali
fuente

Respuestas:

38

Yo empecé

while true; do yad; sleep 60; done &

y cerré la terminal para probarlo, ahora tengo el mismo problema.

Si ya cerró la terminal, ha comenzado el ciclo

Vamos a obtener una visión general de los procesos en ejecución con ps fjx, las últimas líneas en mi máquina leen

 2226 11606 11606 19337 ?           -1 S     1000   0:00  \_ /bin/bash
11606 22485 11606 19337 ?           -1 S     1000   0:00  |   \_ sleep 10
 2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
 9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad
    1  2215  2215  2215 ?           -1 Ss    1000   0:00 /lib/systemd/systemd --user
 2215  2216  2215  2215 ?           -1 S     1000   0:00  \_ (sd-pam)

Puede ver yadcomo un subproceso de /bin/bash, si lo cierro yadcambia a sleep 60la salida de ps. Si la vista de árbol es demasiado confusa, también puede buscar la salida de la siguiente manera 1 :

ps fjx | grep "[y]ad"  # or respectively
ps fjx | grep "[s]leep 60"

Las líneas de salida comienzan con dos números, el primero es el PPID, el ID del proceso principal y el segundo es el PID, el ID del proceso en sí. Es por eso que 9411aparece en ambas filas aquí:

2226  9411  9411  8383 ?           -1 S     1000   0:00  \_ /bin/bash
9411 17674  9411  8383 ?           -1 Sl    1000   0:00      \_ yad

Esa es la bashsubshell que queremos matar y acabamos de descubrir su PID, así que ahora todo lo que queda es un simple

kill 9411  # replace 9411 with the PID you found out!

y la molesta subshell se ha ido para siempre.

1 : La notación como en grep "[y]ad"lugar de simplemente grep yadevita que el grepproceso en sí aparezca en la lista de resultados.


Si todavía tienes la terminal abierta

bashproporciona la variable $!, que "se expande al ID de proceso del trabajo colocado más recientemente en segundo plano", por lo que lo siguiente simplemente elimina el último proceso en segundo plano:

kill $!

Si es que no el último proceso, solo se puede obtener una lista de puestos de trabajo que se ejecuta con la jobsorden interna, salida de ejemplo:

[1]-  Running                 while true; do
    yad; sleep 60;
done &
[2]+  Stopped                 sleep 10

Hay dos trabajos en la lista de trabajos, para eliminar uno de ellos puede acceder con el número de trabajo o los accesos directos %, %+("trabajo actual") y %-("trabajo anterior"), por ejemplo, para eliminar el bucle que se está ejecutando en segundo plano. podría hacer

kill %1  # or
kill %-

y para matar el sleep 10trabajo suspendido :

kill %2  # or
kill %+  # or
kill %
postre
fuente
5

Tengo que tener en cuenta que cuando cierras la terminal donde ingresaste ese comando, el subcomando debería haber muerto junto con él. Intentar reproducir esto mostró este comportamiento.

Ahora, suponiendo que realmente se encuentre en una situación en la que esto no sucedió, una forma de matar el programa que dejó ejecutándose en segundo plano, que fue causado por &el final del comando, es la siguiente:

  1. Abra un nuevo shell y ejecútelo echo $$para anotar su PID (ID de proceso) actual, de modo que no elimine su propia sesión.
  2. Identifique el PID del programa que cree que aún se está ejecutando; puede hacer esto usando el ps -ef | grep $SHELLcomando para encontrar qué programas están ejecutando un shell.
  3. Observe la segunda columna de la izquierda y observe el valor numérico que difiere de su echo $$resultado anterior; Este es el PID que quieres matar.
  4. Ejecute el kill -SIGTERM <pid>comando, donde <pid>está el valor numérico que identificó en el paso 3
  5. Confirme que el programa ya no se está ejecutando repitiendo el paso 2

También puede reiniciar su sesión o su computadora, pero lo anterior le permitirá evitar eso.

code_dredd
fuente
2
También puede usar toppara matar el proceso presionando k, luego ingresando el PID, luego presionando enter dos veces.
luk3yx
-1

Esto &hará que el terminal cree un nuevo proceso y haga que su código se ejecute dentro de él. Entonces su código se vuelve independiente del proceso terminal. Incluso si cierra la terminal, el nuevo proceso en el que se está ejecutando su código no se detendrá. Entonces, elimine &o haga ps -aux, ubique su proceso y elimínelo kill (process id).

Dr4ke the b4dass
fuente
-3

Generalmente bg para fondo fg para primer plano. Si usa & symbol use fg, se mostrará el programa en ejecución actual. Presione Ctrl + C para matar.

Curioso
fuente
3
Usar bg/ fgno funcionará una vez que se desconecte el terminal bash. No podría volver a adjuntar usando reptyrporque bashtiene procesos secundarios ( sleep).
xiota
Cerró la terminal porque matará ese proceso. Así que la próxima vez usará fg para cerrar el programa. Simple
Curioso
@Curious es la próxima vez. Pero OP pregunta por esta vez.
RonJohn