Was ist der Unterschied zwischen Strg-Z und Kill-Stop?

14

Wenn ich einen Befehl ( makein 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 fgden 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 -STOPund wie kann ich das Verhalten des ersteren in einem Shell-Skript ermitteln?

Taymon
quelle
Und ja, makewird rekursiv ausgeführt. In der Tat denke ich, dass es mehrere Ebenen tief geht.
Taymon

Antworten:

12

Was unterscheidet Strg-Z von kill -STOPund wie kann ich das Verhalten des ersteren in einem Shell-Skript ermitteln?

CTRL-ZIn 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 wird fg).

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.

peterph
quelle
4

Sie möchten den makeProzess nicht stoppen . Sie möchten den makeProzess und alle untergeordneten Prozesse stoppen . Ich wette make wurde rekursiv ausgeführt.

Sie könnten versuchen set -m, dann %1anstelle von verwenden "$subpid".

Das set -mermö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 .

sourcejedi
quelle
4

Sie können ein Signal an alle Prozesse in einer Prozessgruppe senden, wenn Sie einen negativen PID-Wert (PGID) eines Sitzungsleiters angeben.

kill -STOP -"$subpid"

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:

killall -STOP make

Der Unterschied zwischen Strg + Z und kill -STOP:

  • Strg-Z sendet tatsächlich TSTP, das blockiert werden kann.
  • STOP kann nicht blockiert werden.
Jurij
quelle
Der PGID Ansatz funktionierte nicht, und erzeugt die folgende Zeile der Ausgabe: /usr/local/bin/myscript: line 38: kill: (-10202) - No such process. Die Hintergrundprozesse liefen weiter. Ich denke nicht, dass der killallAnsatz funktionieren würde, da einige der Teilprozesse sheher als zu sein scheinen make.
Taymon
Es scheint, dass der Prozess, an den Sie das Signal senden, bereits abgeschlossen ist. Unterprozesse mit dem Namen sh werden von make erzeugt. In Ihrem Fall von make und vielen Unterprozessen wäre es wahrscheinlich das Beste, PIDs aller Kinder zu erhalten und sie alle zu stoppen.
Jurij
Es funktionierte schließlich, als ich es manuell von der Shell aus tat, aber nicht in einem Shell-Skript. Ich denke, das liegt daran, dass die Root-PID (von der die anderen ihre PGID geerbt haben) die des ersten makeBefehls war, aber als ich sie vom Skript aus ausführte, war die Root-PID vom Shell-Skript selbst .
Taymon
1

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) und bg (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 jobsBefehl, um sie aufzulisten. Die Ausgabe erfolgt wie folgt:

[1]-  Stopped                 cat
[2]+  Stopped                 vi

Wie kann ich einen angehaltenen Prozess im Hintergrund beenden?

Mit dem killBefehl:

kill %nWobei n die Jobnummer ist (die in eckigen Klammern von der Jobausgabe), also möchte ich cat: töten kill %1.

antzshrek
quelle