Cuando ejecuto un comando ( make
en un proyecto grande) desde el shell, puedo escribir Ctrl-Z para detener el proceso y volver al shell. Posteriormente, puedo ejecutar fg
para continuar el proceso.
Estoy tratando de escribir un script de shell para automatizar esto (específicamente, para verificar la temperatura de mi CPU cada pocos segundos y detener el proceso si hace demasiado calor, ya que mi computadora es propensa a sobrecalentarse). Mi primer intento funcionó así (simplificado):
make &
subpid="$!"
sleep 2
# If the CPU temperature is too high...
kill -STOP "$subpid"
sleep 2
# If the CPU temperature has dropped to safe levels...
kill -CONT "$subpid"
wait "$subpid"
Lamentablemente, esto no funcionó; el envío de SIGSTOP al proceso no lo detuvo (como lo demuestra su continuo envío de salida al terminal). Corrí make &
en la línea de comando, envié SIGSTOP y verifiqué el estado del proceso con ps
; estaba en la lista como detenido (y comenzó de nuevo cuando envié SIGCONT), ¡pero todavía estaba arrojando resultados y elevando mi temperatura central! Detenerlo con Ctrl-Z nunca tuvo este problema, pero no sé cómo hacerlo en un script.
¿Qué hace diferente a Ctrl-Z kill -STOP
y cómo puedo obtener el comportamiento del primero en un script de shell?
fuente
make
se está ejecutando recursivamente. De hecho, creo que va varios niveles de profundidad.Respuestas:
CTRL-Z
generalmente envía SIGTSTP (que puede bloquearse) y, aparte de otras cosas, los shells a menudo restablecen tty a un estado previamente guardado en estas ocasiones. Sin embargo, lo que es más importante, el grupo de proceso de terminal de control se establece en el PID del shell (y luego nuevamente en un PID de un trabajo reanudado confg
).Volviendo a su problema original: el uso de una escala de frecuencia dependiente de la temperatura como, por ejemplo, Cpufreqd podría ser un mejor martillo para su uña.
fuente
No quieres detener el
make
proceso; desea detener elmake
proceso y todos sus procesos secundarios. Apuesto a que make se ejecutaba recursivamente.Podrías intentar
set -m
, luego usar en%1
lugar de"$subpid"
.El
set -m
permite que "el control de trabajos", que está fuera de las secuencias de comandos en el interior por defecto. Creo que debería funcionar para su caso de uso, aunque la gente parece pensar que es una mala idea en general .fuente
Puede enviar una señal a todos los procesos en un grupo de procesos si especifica un valor PID negativo: PGID de un líder de sesión.
Nota: Para ejecutar un programa en una nueva sesión, use
setsid make
. Pero en su caso, creo que no es necesario. Sin embargo, si make se ejecuta de forma recursiva, cada instancia de make podría ser su propio líder (no estoy seguro de eso).Otra opción podría ser usar
killall
:La diferencia entre Ctrl + Z y kill -STOP:
fuente
/usr/local/bin/myscript: line 38: kill: (-10202) - No such process
. Los procesos en segundo plano continuaron ejecutándose. No creo que elkillall
enfoque funcione porque algunos de los subprocesos parecen serlo ensh
lugar de hacerlomake
.make
comando, pero cuando lo hice desde el script, el PID raíz era del script de shell. .Ctrl+ Cse usa para matar un proceso con señal
SIGINT
, en otras palabras, es una muerte educada .Ctrl+ Z se utiliza para suspender un proceso enviándole la señal SIGSTP , que es como una señal de suspensión, que se puede deshacer y el proceso se puede reanudar nuevamente.
Sin embargo, cuando se suspende un proceso, podemos reanudarlo nuevamente
fg
(reanudar en primer plano) ybg
(reanudar en segundo plano) , pero no puedo reanudar un proceso finalizado, esa es una diferencia entre usar Ctrl+ Cy Ctrl+ Z.¿Cómo ver el proceso suspendido?
Cuando tiene varios comandos suspendidos, para tenerlos en la lista, usa el
jobs
comando y la salida será:¿Cómo matar un proceso suspendido en segundo plano?
Al usar el
kill
comando:kill %n
donde n es el número de trabajo (el que está entre corchetes de la salida de puestos de trabajo), así que quiero matar gato:kill %1
.fuente