Wenn ich einen Befehl ( make
in einem großen Projekt) über die Shell ausführe , kann ich Strg-Z eingeben, um den Prozess anzuhalten und zur Shell zurückzukehren. Anschließend kann ich fg
den Vorgang fortsetzen.
Ich versuche, ein Shell-Skript zu schreiben, um dies zu automatisieren (insbesondere, um meine CPU-Temperatur alle paar Sekunden zu überprüfen und den Prozess anzuhalten, wenn es zu heiß wird, da mein Computer zu Überhitzung neigt). Mein erster Versuch hat so funktioniert (vereinfacht):
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"
Leider hat das nicht funktioniert; Das Senden von SIGSTOP an den Prozess hat ihn nicht angehalten (was sich daran zeigt, dass weiterhin Ausgaben an das Terminal gesendet werden). Ich lief make &
in der Befehlszeile, sendete SIGSTOP und überprüfte den Prozessstatus mit ps
; Es wurde als gestoppt aufgeführt (und als ich SIGCONT sendete, wurde es erneut gestartet), aber es spuckte immer noch Leistung aus und erhöhte meine Kerntemperatur! Das Stoppen mit Strg-Z hatte nie dieses Problem, aber ich weiß nicht, wie man das in einem Skript macht.
Was unterscheidet Strg-Z von kill -STOP
und wie kann ich das Verhalten des ersteren in einem Shell-Skript ermitteln?
quelle
make
wird rekursiv ausgeführt. In der Tat denke ich, dass es mehrere Ebenen tief geht.Antworten:
CTRL-Z
In der Regel wird SIGTSTP (das blockiert werden kann) gesendet, und - abgesehen von anderen Dingen - werden Shells bei diesen Gelegenheiten häufig auf einen zuvor gespeicherten Status zurückgesetzt. Noch wichtiger ist jedoch, dass die Prozessgruppe des steuernden Terminals auf die PID der Shell festgelegt wird (und dann erneut auf eine PID eines Jobs, mit dem wieder aufgenommen wirdfg
).Zurück zu Ihrem ursprünglichen Problem: Die Verwendung einer temperaturabhängigen Frequenzskalierung wie z. B. Cpufreqd ist möglicherweise ein besserer Hammer für Ihren Nagel.
quelle
Sie möchten den
make
Prozess nicht stoppen . Sie möchten denmake
Prozess und alle untergeordneten Prozesse stoppen . Ich wette make wurde rekursiv ausgeführt.Sie könnten versuchen
set -m
, dann%1
anstelle von verwenden"$subpid"
.Das
set -m
ermöglicht „Jobsteuerung“, die standardmäßig innerhalb Skripte ist ausgeschaltet. Ich denke, es sollte für Ihren Anwendungsfall funktionieren, obwohl die Leute zu denken scheinen, dass es im Allgemeinen eine schlechte Idee ist .quelle
Sie können ein Signal an alle Prozesse in einer Prozessgruppe senden, wenn Sie einen negativen PID-Wert (PGID) eines Sitzungsleiters angeben.
Hinweis: Um ein Programm in einer neuen Sitzung auszuführen, verwenden Sie
setsid make
. Aber in Ihrem Fall denke ich, dass es nicht benötigt wird. Wenn make jedoch rekursiv ausgeführt wird, kann jede make-Instanz ihr eigener Anführer sein (da bin ich mir nicht sicher).Eine andere Möglichkeit könnte sein
killall
:Der Unterschied zwischen Strg + Z und kill -STOP:
quelle
/usr/local/bin/myscript: line 38: kill: (-10202) - No such process
. Die Hintergrundprozesse liefen weiter. Ich denke nicht, dass derkillall
Ansatz funktionieren würde, da einige der Teilprozessesh
eher als zu sein scheinenmake
.make
Befehls war, aber als ich sie vom Skript aus ausführte, war die Root-PID vom Shell-Skript selbst .Ctrl+ Cwird verwendet, um einen Prozess mit einem Signal abzubrechen
SIGINT
, mit anderen Worten, es ist ein höflicher Abbruch .Ctrl+ Z wird verwendet, um einen Prozess zu unterbrechen, indem das Signal SIGSTP gesendet wird , das wie ein Schlafsignal aussieht , das rückgängig gemacht und der Prozess wieder aufgenommen werden kann.
Wenn ein Prozess angehalten wird, können wir ihn durch
fg
(im Vordergrund wieder aufnehmen) undbg
(im Hintergrund wieder aufnehmen) wieder aufnehmen , aber ich kann einen angehaltenen Prozess nicht wieder aufnehmen, das ist ein Unterschied zwischen der Verwendung von Ctrl+ C& Ctrl+ Z.Wie sehen suspendierte Prozess?
Wenn Sie mehrere angehaltene Befehle haben, verwenden Sie den
jobs
Befehl, um sie aufzulisten. Die Ausgabe erfolgt wie folgt:Wie kann ich einen angehaltenen Prozess im Hintergrund beenden?
Mit dem
kill
Befehl:kill %n
Wobei n die Jobnummer ist (die in eckigen Klammern von der Jobausgabe), also möchte ich cat: tötenkill %1
.quelle