Lorsque j'exécute une commande ( make
sur un grand projet) à partir du shell, je peux taper Ctrl-Z pour arrêter le processus et revenir au shell. Par la suite, je peux courir fg
pour continuer le processus.
J'essaie d'écrire un script shell pour automatiser cela (en particulier, pour vérifier la température de mon processeur toutes les quelques secondes et arrêter le processus s'il fait trop chaud, car mon ordinateur est sujet à une surchauffe). Ma première tentative a fonctionné comme ceci (simplifié):
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"
Malheureusement, cela n'a pas fonctionné; l'envoi de SIGSTOP au processus ne l'a pas interrompu (comme en témoigne le fait qu'il continue d'envoyer la sortie au terminal). J'ai couru make &
sur la ligne de commande, envoyé SIGSTOP et vérifié l'état du processus avec ps
; il a été répertorié comme arrêté (et a recommencé lorsque j'ai envoyé SIGCONT), mais il crachait toujours la sortie et augmentait ma température à cœur! L'arrêter avec Ctrl-Z n'a jamais eu ce problème, mais je ne sais pas comment faire cela dans un script.
Qu'est-ce qui différencie Ctrl-Z kill -STOP
et comment puis-je obtenir le comportement du premier dans un script shell?
la source
make
est exécuté de manière récursive. En fait, je pense que cela va à plusieurs niveaux.Réponses:
CTRL-Z
envoie généralement SIGTSTP (qui peut être bloqué), et - à part d'autres choses - les shells réinitialisent souvent tty dans un état précédemment enregistré à ces occasions. Plus important cependant, le groupe de processus du terminal de contrôle est défini sur le PID du shell (puis sur un PID d'un travail repris avecfg
).Revenons à votre problème d'origine: l'utilisation d'une mise à l'échelle de fréquence dépendante de la température comme par exemple Cpufreqd pourrait être en fait un meilleur marteau pour votre ongle.
la source
Vous ne voulez pas arrêter le
make
processus; vous voulez arrêter lemake
processus et tous ses processus enfants. Je parie que make était exécuté de manière récursive.Vous pouvez essayer
set -m
, puis utiliser à la%1
place de"$subpid"
.Le
set -m
permet le "contrôle des travaux", qui est désactivé par défaut dans les scripts. Je pense que cela devrait fonctionner pour votre cas d'utilisation, bien que les gens semblent penser que c'est une mauvaise idée en général .la source
Vous pouvez envoyer un signal à tous les processus d'un groupe de processus si vous spécifiez une valeur PID négative - PGID d'un chef de session.
Remarque: pour exécuter un programme dans une nouvelle session, utilisez
setsid make
. Mais dans votre cas, je pense que ce n'est pas nécessaire. Cependant, si make est exécuté récursivement, chaque instance de make pourrait être son propre leader (je n'en suis pas sûr).Une autre option pourrait être d'utiliser
killall
:La différence entre Ctrl + Z et kill -STOP:
la source
/usr/local/bin/myscript: line 38: kill: (-10202) - No such process
. Les processus d'arrière-plan ont continué de s'exécuter. Je ne pense pas que l'killall
approche fonctionnerait parce que certains des sous-processus semblent l'êtresh
plutôt quemake
.make
commande, mais quand je l'ai fait à partir du script, le PID racine était du script shell lui-même .Ctrl+ Cest utilisé pour tuer un processus avec un signal
SIGINT
, en d'autres termes, c'est un kill poli .Ctrl+ Z est utilisé pour suspendre un processus en lui envoyant le signal SIGSTP , qui est comme un signal de veille, qui peut être annulé et le processus peut être repris à nouveau.
Cependant, lorsqu'un processus est suspendu, nous pouvons le reprendre à nouveau par
fg
(reprise au premier plan) etbg
(reprise en arrière-plan) , mais je ne peux pas reprendre un processus interrompu, c'est une différence entre l'utilisation de Ctrl+ C& Ctrl+ Z.Comment afficher le processus suspendu?
Lorsque vous avez plusieurs commandes suspendues, pour les avoir répertoriées, vous utilisez la
jobs
commande et la sortie sera:Comment tuer un processus suspendu en arrière-plan?
En utilisant la
kill
commande:kill %n
où n est le nombre d'emplois (celui entre crochets de la sortie de l' emploi), donc je veux tuer le chat:kill %1
.la source