Pregunta

Tengo un script bash que hace algún tipo de procesamiento en paralelo en un bucle. No quiero que el proceso paralelo al pico de la CPU, así que usar un comando del sueño. He aquí una versión simplificada.

(while true;do sleep 99999;done)&

Así que ejecutar la línea por encima de un golpe rápido y conseguir algo como: [1] 12345

Donde [1] es el número de trabajo y 12345 es el identificador de proceso (pid) del bucle while. Hago un kill 12345 y sale:

[1]+  Terminated              ( while true; do
    sleep 99999;
done )

Parece que todo el guión se dio por terminado. Sin embargo, hago un ps aux|grep sleep y encontrar el comando del sueño es todavía fuerte pero con su propio PID! Puedo matar al sleep y todo parece estar bien. Sin embargo, si tuviera que matar al sueño en primer lugar, el bucle mientras se inicia un nuevo PID sleep. Esto es una sorpresa para mí ya que el sueño no es paralelo al bucle while. El bucle en sí es una sola ruta de ejecución.

Así que tengo dos preguntas:

  1. ¿Por qué el comando sleep obtener su propio ID de proceso?
  2. ¿Cómo matar fácilmente a la while y el sueño?
¿Fue útil?

Solución

  1. El sueño tiene su propia PID porque es un proceso en ejecución y esperando. Trate which sleep para ver donde está.
  2. Se puede utilizar ps -uf para ver el árbol de procesos en su sistema. Desde allí se puede determinar que la PPID (padre PID) de la concha (el que ejecuta el bucle) del sueño es.

Otros consejos

¿Usted ha intentado hacer kill %1, donde 1 es el número que se obtiene después de lanzar el comando en segundo plano?

Lo hice en este momento después de lanzar (while true;do sleep 99999;done)& y correctamente por terminada la misma.

"ps --ppid" selecciona todos los procesos con el pid principal especificado, por ejemplo:

$ (while true;do sleep 99999;done)&
[1] 12345

$ ppid=12345 ; kill -9 $ppid $(ps --ppid $ppid -o pid --no-heading)

Puede matar al grupo de procesos.

Para encontrar el grupo de procesos de la ejecución de proceso:

ps --no-headers -o "%r" -p 15864

A continuación, matar al grupo de procesos usando:

kill -- -[PGID]

Puede hacerlo todo en un solo comando. Vamos a tratar de usted mismo:

$ (while true;do sleep 99999;done)&
[1] 16151

$ kill -- -$(ps --no-headers -o "%r" -p 16151)
[1]+  Terminated              ( while true; do
    sleep 99999;
done )
  1. Debido a que "el sueño" es un proceso, no una acumulación de funciones o similares

  2. Se puede hacer lo siguiente:

    (while true;do sleep 99999;done)&
    whilepid=$!
    kill -- -$whilepid
    

El código anterior mata el grupo de proceso, debido a que el PID se especifica como un número negativo (por ejemplo -123 en lugar de 123). Además, se utiliza el $! variable, que almacena el PID del proceso ejecutado más recientemente.

Nota: Al ejecutar cualquier proceso en segundo plano en modo interactivo (es decir, utilizando la línea de comandos del sistema) se crea un nuevo grupo de procesos, que es lo que le está pasando. De esa manera, es relativamente fácil de "Kill 'Em All", ya que sólo hay que matar a todo el grupo de procesos. Sin embargo, cuando se hace lo mismo dentro de un script, no se crea ningún nuevo grupo, porque todos los nuevos procesos pertenecen a la secuencia de comandos PID, incluso si se ejecutan en segundo plano (control de puestos de trabajo está desactivado por defecto). Para habilitar el control de puestos de trabajo en un script, sólo hay que poner el siguiente al principio de la secuencia de comandos:

#!/bin/bash

set -m

Para matar el bucle while y la sleep usando $! también se puede utilizar un manejador de señales trap dentro del subnivel.

(trap 'kill ${!}; exit' TERM; while true; do sleep 99999 & wait ${!}; done)&
kill -TERM ${!}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top