Jan Novak <
rep...@gmail.com>:
>Am 25.11.20 um 15:02 schrieb Helmut Waitzmann:
>> Oder man nutzt Prozessgruppen (job groups, wie Du unten
>> andeutest) und schickt das ursprüngliche Signal nicht an den
>> Skript‐Prozess sondern an die Prozessgruppe, der der
>> Skript‐Prozess mitsamt seinem «rsync»‐Prozess angehört: Dann
>> kommt das Signal sowohl beim Skript als auch beim
>> «rsync»‐Prozess an. Das erfordert allerdings – wenn man
>> Kollateralschäden vermeiden will –, dass das Skript in einer
>> eigenen Prozessgruppe gestartet wird.
>
>ok... ist für mich völliges Neuland.
>
Als Einstieg schau mal im Handbuch credentials(7) nach den
Abschnitten «Process ID» und «Process group ID and session ID» und
im Bash‐Handbuch nach dem Abschnitt «JOB CONTROL».
Ganz kurz:
Jeder Prozess hat eine eigene Nummer (process id, pid). Solange
dieser Prozess lebt oder zwar gestorben, aber noch nicht begraben
ist, hat kein anderer Prozess dieselbe Nummer.
Er gehört genau einer Prozessgruppe, auch Job genannt, an. Die
Prozessgruppe hat eine eigene Nummer (process group id, pgid).
Solange Prozesse in dieser Prozessgruppe leben oder zwar
gestorben, aber noch nicht begraben sind, hat keine andere
Prozessgruppe dieselbe Nummer. Zu einer Prozessgruppe kann mehr
als ein Prozess gehören.
Eine Prozessgruppe wird erzeugt, indem ein Prozess den
Betriebssystemkern bittet, ihn aus seiner bisherigen Prozessgruppe
herauszunehmen und in eine neue, frisch erzeugte zu stecken. Die
neue Prozessgruppe bekommt die Nummer des Prozesses als
Gruppennummer. => Die Prozessgruppennummer des Prozesses ist
jetzt gleich seiner Prozessnummer. Man nennt den Prozess jetzt
Prozessgruppenführer (process group leader, job group leader).
Jede Prozessgruppe (und damit alle Prozesse der Gruppe ebenfalls)
gehört einer Sitzung an. Die Sitzung hat eine eigene Nummer
(session id, sid). Solange Prozesse in dieser Sitzung leben oder
zwar gestorben, aber noch nicht begraben sind, hat keine andere
Sitzung dieselbe Nummer. Zu einer Sitzung kann mehr als eine
Prozessgruppe gehören.
Eine Sitzung wird erzeugt, indem ein Prozess den
Betriebssystemkern bittet, ihn aus seiner bisherigen Prozessgruppe
und Sitzung herauszunehmen und in eine neue, frisch erzeugte
Prozessgruppe und Sitzung zu stecken. Die neue Prozessgruppe und
Sitzung erhalten jeweils die Nummer des Prozesses als Gruppen‐
bzw. Sitzungsnummer. => Die Prozessgruppen‐ und die
Sitzungsnummer des Prozesses sind jetzt gleich seiner
Prozessnummer. Man nennt den Prozess jetzt Sitzungsführer
(session leader).
Ein Terminal nennt man Steuerterminal (controlling terminal), wenn
es gewissen Prozessen (s. u.) auf Tastendruck Job‐Control‐Signale,
wie beispielsweise ein INT‐ (interrupt) oder ein TSTP‐ (terminal
stop) Signal schicken kann. Dadurch können Prozesse auf
Tastendruck abgebrochen oder angehalten werden. Welche Prozesse
die Adressaten dieser Signale sind, wird durch die Zuordnung des
Steuerterminals zu genau einer Sitzung und genau einer
Prozessgruppe festgelegt:
Der Betriebssystemkern vermerkt bei jedem Steuerterminal die
Nummer der Sitzung, zu der es gehört. Außerdem vermerkt er bei
dem Terminal eine Prozessgruppe, die zur Sitzung gehört. Die
Prozesse in dieser Gruppe erhalten die Signale, die das Terminal
auf Tastendruck verschickt. Man sagt, diese Prozessgruppe «läuft
im Vordergrund».
Umgekehrt ist jede Sitzung höchstens einem Steuerterminal
zugeordnet. (Es gibt also auch Sitzungen ohne Steuerterminal.)
Beispiel:
Im Steuerterminal /dev/pts/12 läuft ein interaktiver «bash». Dort
hat man das Kommando
COLUMNS=60 ps -o ppid -o sid -o pgid -o pid -o tpgid -o stat \
-o args 2>&1 |
less
eingetippt und sieht im Terminal in der Ausgabe von «less» jetzt
folgendes:
PPID SID PGID PID TPGID TT STAT COMMAND
12345 12345 23456 23456 23456 pts/12 R+ ps -o ppid -o si
12345 12345 23456 2468 23456 pts/12 S+ less
32724 12345 12345 12345 23456 pts/12 Ss /usr/bin/bash
Beobachtungen:
Die «less»‐ und «ps»‐Prozesse sind Kindprozesse des
«bash»‐Prozesses: In der Spalte «PPID» steht bei ihnen die
Prozessnummer des «bash»‐Prozesses.
Alle 3 Prozesse gehören derselben Sitzung mit der Nummer 12345
(Spalte «SID») an.
Die 3 Prozesse verteilen sich auf 2 Prozessgruppen (Spalte
«PGID»): 12345 und 23456.
Alle 3 Prozesse haben «/dev/pts/12» als Steuerterminal (Spalte
«TT»).
Das Terminal hat im Augenblick die Prozessgruppe 23456 als
Vordergrundprozessgruppe (Spalte «TPGID»). Die Prozesse der
Vordergrundprozessgruppe sind in der Spalte «STAT» mit einem «+»
gekennzeichnet. => Im Augenblick läuft das «ps»‐«less»‐Kommando
im Vordergrund.
Der Sitzungsführer ist der Prozess mit der Nummer 12345
(pid=pgid=sid), «/usr/bin/bash». Das «s» in der Spalte «STAT»
zeigt die Sitzungsführerschaft an.
Im Augenblick der Erstellung der Ausgabe lief der «ps»‐Prozess
(das «R» in der Spalte «STAT»). Die anderen beiden Prozesse
hatten nichts zu tun (das «S» in der Spalte «STAT»).
(Für die Grafik bitte Festbreitenschrift verwenden:)
Sitzung 12345
+----------------------+ <-----.
| sid=12345 | \
| terminal=/dev/pts/12 >------. \
| +---------------+ | \ \ Steuerterminal /dev/pts/12
| | pgid=12345 | | `----> +----------------------+
| | +-----------+ | | \ | terminal=/dev/pts/12 |
| | | pid=12345 | | | `-< sid=12345 |
| | +-----------+ | | .-< tpgid=23456 |
| +---------------+ | / +----------------------+
| | /
| +---------------+ <-------------'
| | pgid=23456 | |
| | +-----------+ | |
| | | pid=23456 | | |
| | +-----------+ | |
| | | |
| | +-----------+ | |
| | | pid=2468 | | |
| | +-----------+ | |
| +---------------+ |
+----------------------+
Wenn man jetzt Ctrl‐Z tippt, schickt der Betriebssystemkern ein
TSTP‐Signal an alle Prozesse in der Prozessgruppe, deren
Gruppennummer im Steuerterminal vermerkt (tpgid=23456) ist.
Dadurch werden die Prozesse der Vordergrundprozessgruppe (also die
Prozesse «less» und – wenn er sich noch nicht beendet hätte –
«ps») gestoppt. (Dass «less» gestoppt ist, sieht man am «T» in
der Spalte «STAT» in der folgenden Prozessliste.)
Weil der «less»‐Prozess ein Kind des «bash»‐Prozesses ist (siehe
die Spalte «PPID»), merkt der «bash»‐Prozess, dass der
«less»‐Prozess gestoppt wurde. Jetzt läuft also kein
Vordergrund‐Job mehr, auf den der «bash»‐Prozess warten müsste.
Deshalb macht er sich selbst zum Vordergrund‐Job: Er bittet das
Betriebssystem, die Prozessgruppe im Terminal auf seine
Prozessgruppe, die Prozessgruppe 12345, umzustellen. Dass das
geschehen ist, sieht man an der Nummer «12345» in der Spalte
«TPGID» und dem «+» in der Spalte «STAT»):
PPID SID PGID PID TPGID TT STAT COMMAND
12345 12345 23456 2468 12345 pts/12 T less
32724 12345 12345 12345 12345 pts/12 Ss+ /usr/bin/bash
Sitzung 12345
+----------------------+ <-----.
| sid=12345 | \
| terminal=/dev/pts/12 >------. \
| +---------------+ <------. \ \ Steuerterminal /dev/pts/12
| | pgid=12345 | | \ `----> +----------------------+
| | +-----------+ | | \ \ | terminal=/dev/pts/12 |
| | | pid=12345 | | | \ `-< sid=12345 |
| | +-----------+ | | `-------< tpgid=12345 |
| +---------------+ | +----------------------+
| |
| +---------------+ |
| | pgid=23456 | |
| | +-----------+ | |
| | | pid=23456 | | |
| | +-----------+ | |
| | | |
| | +-----------+ | |
| | | pid=2468 | | |
| | +-----------+ | |
| +---------------+ |
+----------------------+
>Das heisst, ein set -m in obigem Beispiel würde nicht schaden, da das
>Script vom cron gestartet wird?
Ja. Dazu müsste im Crontab etwa folgendes stehen:
set -m && hier_der_Aufruf_vom_Skript
Es könnte aber je nach Shell sein, dass «set -m» nichts bewirkt
außer, dass der Shell sich beschwert, dass er kein job control
nutzen kann, weil er kein Steuerterminal hat, denn Cron‐Jobs
laufen ohne Terminal.
Auf Debian Buster ausprobiert:
«bash» (egal, ob in der nativen oder der zu POSIX kompatiblen
Betriebsart), startet das Skript in einer neuen Prozessgruppe.
«dash» beschwert sich «can't access tty; job control turned off»
und startet das Skript, ohne eine neue Prozessgruppe zu erzeugen.
Es kommt also darauf an, welchem Shell die im crontab enthaltenen
Kommandozeilen zur Ausführung übergeben werden.