Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Script mit mehreren rsync Aufrufen beenden

29 views
Skip to first unread message

Jan Novak

unread,
Nov 24, 2020, 4:43:09 AM11/24/20
to
Hallo,

auf einem Server werden zu verschiedenen Zeiten mit verschiedenen (bash)
scripten mehrere rsyncs (nacheinander) gestartet.

Mit entsprechnenden PID Mechanismen, kann ich das aufgerufene Script
zwar extern beenden, jedoch wird dann immer noch der nächste rsync im
script gestartet, was nicht gewünscht ist.

Ein "killall rsync" geht auch nicht, weil andere rsyncs, aus anderen
scripten, weiter laufen sollen.

Meine Frage lautet also, wie kann ich ein Script beenden und alle
weiteren darin enthaltenen rsync aufrufe beenden/abbrechen/gar nicht
erst starten lassen?


Jan

Stefan Wiens

unread,
Nov 24, 2020, 5:21:25 AM11/24/20
to
Jan Novak <rep...@gmail.com> writes:

> auf einem Server werden zu verschiedenen Zeiten mit verschiedenen
> (bash) scripten mehrere rsyncs (nacheinander) gestartet.
>
> Mit entsprechnenden PID Mechanismen, kann ich das aufgerufene Script
> zwar extern beenden, jedoch wird dann immer noch der nächste rsync im
> script gestartet, was nicht gewünscht ist.

Ein "beendetes" Script kann keine weiteren Prozesse starten.

> Ein "killall rsync" geht auch nicht, weil andere rsyncs, aus anderen
> scripten, weiter laufen sollen.

"killall" ? Kein Kommentar.

> Meine Frage lautet also, wie kann ich ein Script beenden und alle
> weiteren darin enthaltenen rsync aufrufe beenden/abbrechen/gar nicht
> erst starten lassen?

Zunächst nachdenken. Wann kann bzw. soll das Script sinnvoll
weitermachen? Den Exit-Value der gestarteten Commands auswerten.

Welches Problem soll denn konkret behoben werden?

--
Stefan

Jan Novak

unread,
Nov 24, 2020, 5:31:54 AM11/24/20
to
Am 24.11.20 um 11:21 schrieb Stefan Wiens:
Beispiel:

#!/bin/bash

##################### check and kill #####################
pidFile="/var/run/$(basename $0 .sh).pid"
[ -e $pidFile ] && pid=$(cat $pidFile)
if [ "$1" ] && [ "$1" = "kill" ]; then
if [ "$pid" ] && [ "$(ps ax|grep $pid|grep -v ps)" ] ; then
echo "Killing pid $pid ..."
kill $pid
else
echo "Nothing to kill."
fi
rm -f $pidFile
exit
fi
if [ "$pid" ] && [ "$(ps ax|grep $pid|grep -v ps|grep -v grep)" ]; then
echo "ERROR: Script $0 always running on $(hostname -f) (
$(hostname -i) ). Exit!" | tee /dev/stderr | mail root
exit
fi
echo $$>$pidFile
##################### check and kill #####################


rsync source dest...
rsync source dest...
rsync source dest...
rsync source dest...
rsync source dest...


Wenn jetzt ein rsync (sub-) Prozess läuft und ich das Script mit dem
Parameter "kill" aufrufe, wird der rsync przess nicht gestoppt.

Jan

Juergen Ilse

unread,
Nov 24, 2020, 6:34:45 AM11/24/20
to
Hallo,
Ungetestete Idee: Fange den Kill mittels "trap" Kommando im script ab, und
lass dein Script vor der Beendigung zuerst seinen parent ($PPID) killen ...

Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)

Stefan Wiens

unread,
Nov 24, 2020, 7:20:05 AM11/24/20
to
Also erstens kommt in deinem Script kein Aufruf von rsync(1) vor. Da
kann niemand sagen, wie du unerwünschte rsync-Prozesse unterdrücken
könntest.

Zweitens hat dein Script offenbar Write-Permissions nach /var/run. Da
sollte man mit dem blauäugigen herum-grep(1)-en in der Ausgabe von ps(1)
vorsichtig sein.

--
Stefan

Stefan Reuther

unread,
Nov 24, 2020, 12:34:36 PM11/24/20
to
Am 24.11.2020 um 10:43 schrieb Jan Novak:
> Meine Frage lautet also, wie kann ich ein Script beenden und alle
> weiteren darin enthaltenen rsync aufrufe beenden/abbrechen/gar nicht
> erst starten lassen?

Irgendwie vermisse ich hier den naheliegenden Ansatz: "kille das Script,
nicht den rsync". Killen des Scripts reißt den rsync mit weg und startet
natürlich auch den nächsten nicht.

(Funktioniert zumindest mit händisch gestartetem Script. Sonst evtl. mal
in die Richtung Job Control / 'set -m' schauen.)

(Und wenn wir bei 'set' unterwegs sind: 'set -e' bricht das Skript ab,
sobald ein Kommando fehlschlägt, z.B. das extern getötete rsync.)


Stefan

Jan Novak

unread,
Nov 25, 2020, 5:08:59 AM11/25/20
to
Am 24.11.20 um 13:20 schrieb Stefan Wiens:
>> rsync source dest...

> Also erstens kommt in deinem Script kein Aufruf von rsync(1) vor. Da
> kann niemand sagen, wie du unerwünschte rsync-Prozesse unterdrücken
> könntest.

Da oben stehts doch... was soll ich den exakten Aufruf hier posten. Ist
ein rsync -avp mit ssh source dest ... nichst aufregendes.


> Zweitens hat dein Script offenbar Write-Permissions nach /var/run.

Korrekt. Es läuft als root.


>Da sollte man mit dem blauäugigen herum-grep(1)-en in der Ausgabe von ps(1)
> vorsichtig sein.


"Blauäugigem herum-grep'en" ;-)
Scherzkeks. Niemand greppt blauäugig in /var/run...
Du hast scheinbar die Frage nicht verstanden oder nicht richtige
gelesen. Seis drum. Danke dennoch für deinen Kommentar (ausdrücklich
nicht ironisch gemeit)

Jan


Jan Novak

unread,
Nov 25, 2020, 5:11:34 AM11/25/20
to
Am 24.11.20 um 18:23 schrieb Stefan Reuther:
> Am 24.11.2020 um 10:43 schrieb Jan Novak:
>> Meine Frage lautet also, wie kann ich ein Script beenden und alle
>> weiteren darin enthaltenen rsync aufrufe beenden/abbrechen/gar nicht
>> erst starten lassen?
>
> Irgendwie vermisse ich hier den naheliegenden Ansatz: "kille das Script,
> nicht den rsync". Killen des Scripts reißt den rsync mit weg und startet
> natürlich auch den nächsten nicht.

Aber genau das mache ich. Das Script schreibt seinen PID (den des
scriptes, nicht den von rsync) in die pid Datei, welcher letztendlich
zum auslesen und killen genutzt werden soll.


> (Funktioniert zumindest mit händisch gestartetem Script. Sonst evtl. mal
> in die Richtung Job Control / 'set -m' schauen.)

ok.


> (Und wenn wir bei 'set' unterwegs sind: 'set -e' bricht das Skript ab,
> sobald ein Kommando fehlschlägt, z.B. das extern getötete rsync.)

guter Tip. Hatte ich gar nicht dran gedacht.


Jan

Jan Novak

unread,
Nov 25, 2020, 5:12:30 AM11/25/20
to
Am 24.11.20 um 12:34 schrieb Juergen Ilse:
Sehr gute Idee. Diese bedarf zwar noch einiges an (script-) Testsm aber
eine Möglichkeit. Danke!

Jan

Jan Novak

unread,
Nov 25, 2020, 5:38:26 AM11/25/20
to
Am 24.11.20 um 18:23 schrieb Stefan Reuther:
> Am 24.11.2020 um 10:43 schrieb Jan Novak:
> (Und wenn wir bei 'set' unterwegs sind: 'set -e' bricht das Skript ab,
> sobald ein Kommando fehlschlägt, z.B. das extern getötete rsync.)

Verständnisfehler:
Nicht das rsync wird gekillt, sondern das Script, welches die rsync's
nacheinander starten würde.
Und genau dann passiert es, dass - obwohl das script bereits ge'kill't
wurde, der nachfolgende rsync des gekilltem scriptes dennoch aufgerufen
wird.
Genau dies möchte ich verhindern.

Jan

Juergen Ilse

unread,
Nov 25, 2020, 6:12:57 AM11/25/20
to
Eben nichts konkret getestetes, sondern nur eine erste Idee, die moeglicher-
weise ein Ansatz sein koennte ... Eigentlich sollten die child-prozesse
des aufrufenden scripts ein signal abbekommen, dass sie terminieren laesst,
solange sie nicht von ihrem parent "abgekopelt" sind. Also sollte das killen
des aufrufenden scripts (dessen PID du in der Environment-Variablen PPID
stehen hast) eigentlich ein moeglicher Loesungsansatz sein. Er wird aller-
dings bei einem "kill -9" nicht helfen, da sich dieses auch durch ein "trap"
Kommando in einem script meines Wissens nach nicht abfangen laesst ...
Lass uns bitte wissen, ob es funktioniert hat.

Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)

Juergen Ilse

unread,
Nov 25, 2020, 6:23:21 AM11/25/20
to
Hallo,

Jan Novak <rep...@gmail.com> wrote:
Das glaube ich irgendwie nicht so ganz. Ein gekilltes script kann nichts
mehr starten. Bist du sicher, dass du das richtige script gekillt hast?
Ich ging davon aus, dass das script, von dem aus alles gestartet wird,
weitere scripts mit den rsync-kommandos startet. Wenn du von denen eins
killst, geht die Kontrolle an das aufrufende script zurueck, und dieses
startet den naechsten subprocess. Deswegen mein Hinweis, nicht das ent-
sprechende rsync-script, sondern desse parent, das alles aufrufende script,
zu killen. Ich denke, dass dessen schild dann ein HUP abbekommen, dass sie
(sofern sie das nicht abfangen) zum terminieren bringen muesste, und das
uebergeordnete script wird keine neuen rsync-scripts mehr starten, weil es
bereits tot ist. Die PID des aufrufenden Prozesses hast du bei shellscripts
normalerweise in der Environment-Variablen PPID vorliegen.

Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)

Stefan Wiens

unread,
Nov 25, 2020, 6:40:11 AM11/25/20
to
Jan Novak <rep...@gmail.com> writes:

> Am 24.11.20 um 13:20 schrieb Stefan Wiens:
>>> rsync source dest...
>
>> Also erstens kommt in deinem Script kein Aufruf von rsync(1) vor. Da
>> kann niemand sagen, wie du unerwünschte rsync-Prozesse unterdrücken
>> könntest.
>
> Da oben stehts doch... was soll ich den exakten Aufruf hier posten.
> Ist ein rsync -avp mit ssh source dest ... nichst aufregendes.

Sind die rsync-Prozesse irgendwie in den Hintergund gestellt?


>> Zweitens hat dein Script offenbar Write-Permissions nach /var/run.
>
> Korrekt. Es läuft als root.
>
>>Da sollte man mit dem blauäugigen herum-grep(1)-en in der Ausgabe von ps(1)
>> vorsichtig sein.
>
> "Blauäugigem herum-grep'en" ;-)
> Scherzkeks. Niemand greppt blauäugig in /var/run...
> [...]

,----[ <rpinep$4t1$1...@gwaiyur.mb-net.net> ]
| if [ "$pid" ] && [ "$(ps ax|grep $pid|grep -v ps)" ] ; then
`----

Der Suchstring "$pid" darf also sowohl als Teil einer anderen Process-ID
wie auch in den Argumentlisten aller Prozesse vorkommen.

--
Stefan

Helmut Waitzmann

unread,
Nov 25, 2020, 9:02:52 AM11/25/20
to
Stefan Reuther <stefa...@arcor.de>:
>Am 24.11.2020 um 10:43 schrieb Jan Novak:

>> Meine Frage lautet also, wie kann ich ein Script beenden und
>> alle weiteren darin enthaltenen rsync aufrufe
>> beenden/abbrechen/gar nicht erst starten lassen?
>
>Irgendwie vermisse ich hier den naheliegenden Ansatz: "kille das
>Script, nicht den rsync".

In die Richtung würde ich auch gehen. 


>Killen des Scripts reißt den rsync mit weg
>

Das allerdings stimmt nicht, jedenfalls nicht automatisch von
vorne herein:  Ein Prozess, der aufgrund eines empfangenen Signals
beendet wird, tötet seine Kinder nicht grundsätzlich, sondern
lässt sie als Waisen zurück. 

Man könnte aber hergehen und dem Prozess einen Signalbehandler
beispielsweise für das TERM‐, INT‐ und QUIT‐Signal verpassen:
einen Signalbehandler, der dem Kind ein entsprechendes Signal
schickt, dann den Signalbehandler auf SIG_DFL zurückstellt und ein
entsprechendes Signal auch noch an sich selbst schickt. 

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. 

Das ist bei modernen Shells in interaktiver Betriebsart der Fall,
wenn das Skript als interaktives Kommando gestartet wird. 

In nicht‐interaktiver Betriebsart machen das Shells (zumindest
ohne besondere Aufforderung dazu) aber nicht.  (Aber siehe dazu
unten «set -m».) 

Probiere das mit folgendem Shell‐Skript aus:


#!/bin/sh
exec ps -o pgid=Job-Gruppe -o pid=Prozessnummer -o args -p "$$"

Falls das Skript in einer eigenen Job‐Gruppe läuft, enthalten die
Spalten «Job-Gruppe» und «Prozessnummer» dieselbe Zahl;
anderenfalls nicht. 

>und startet natürlich auch den nächsten nicht.
>
>
>(Funktioniert zumindest mit händisch gestartetem Script.
>

Händisch gestartet bedeutet:  Der das Skript startende Shell ist
in der interaktiven Betriebsart.  => Job Control ist aktiviert. 

>Sonst evtl. mal in die Richtung Job Control / 'set -m' schauen.)
>

(Im Shell‐Manual‐Page.) 

Juergen Ilse

unread,
Nov 25, 2020, 9:47:33 AM11/25/20
to
Hallo,

Helmut Waitzmann <nn.th...@xoxy.net> wrote:
> Stefan Reuther <stefa...@arcor.de>:
>>Killen des Scripts reißt den rsync mit weg
>>
> Das allerdings stimmt nicht, jedenfalls nicht automatisch von
> vorne herein:  Ein Prozess, der aufgrund eines empfangenen Signals
> beendet wird, tötet seine Kinder nicht grundsätzlich, sondern
> lässt sie als Waisen zurück. 

Die Children bekommen ein Signal, sofern der Parent sie nicht bereits hat
"verwaisen" lassen (z.B. mittels "nohup" oder in der bash mittels "disown"
von Hintergrundprozessen). Ich bin mir im Moment allerdings nicht sicher,
welches Signal die Children bekommen (moeglicherweise ein HUP, aber die
Default-Reaktion darauf sollte eigentlich auch "Selbstbeendigung" sein).

Gerade noch mal schnell nesucht: Ja, es ist SIGHUP:
-----------------------
Are you ignoring SIGHUP or daemonizing by escaping the session group ? If so, your process won’t be killed with the others. Make sure you aren’t doing neither.

If your process is somehow being created in another process group for some unavoidable reason, then you’ll need to use non portable Linux extensions to detect that the parent died:

prctl(PR_GET_PDEATHSIG, &sig);
signal(sig, on_parent_killed);
-----------------------
Quelle: https://www.reddit.com/r/C_Programming/comments/jykfyx/program_not_dying_when_the_parent_dies/

Es ist fuer ein script auch nicht notwendig, sich selbst zu killen, wenn es
sich auch ganz einfach mit "exit" mit weniger Aufwand selbst beenden kann ...

Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)

Jan Novak

unread,
Nov 25, 2020, 9:55:19 AM11/25/20
to
Am 25.11.20 um 12:40 schrieb Stefan Wiens:
>> "Blauäugigem herum-grep'en" ;-)
>> Scherzkeks. Niemand greppt blauäugig in /var/run...
>> [...]
>
> ,----[ <rpinep$4t1$1...@gwaiyur.mb-net.net> ]
> | if [ "$pid" ] && [ "$(ps ax|grep $pid|grep -v ps)" ] ; then
> `----
>
> Der Suchstring "$pid" darf also sowohl als Teil einer anderen Process-ID
> wie auch in den Argumentlisten aller Prozesse vorkommen.

Ja... deswegen greppt dennoch keiner in /var/run - nur in der Prozess
Liste - und dagegen ist sicher nichts einzuwenden.

Jan

Jan Novak

unread,
Nov 25, 2020, 9:56:32 AM11/25/20
to
Am 25.11.20 um 12:12 schrieb Juergen Ilse:
>> Sehr gute Idee. Diese bedarf zwar noch einiges an (script-) Testsm aber
>> eine Möglichkeit. Danke!
>
> Eben nichts konkret getestetes, sondern nur eine erste Idee, die moeglicher-
> weise ein Ansatz sein koennte ... Eigentlich sollten die child-prozesse
> des aufrufenden scripts ein signal abbekommen, dass sie terminieren laesst,
> solange sie nicht von ihrem parent "abgekopelt" sind. Also sollte das killen
> des aufrufenden scripts (dessen PID du in der Environment-Variablen PPID
> stehen hast) eigentlich ein moeglicher Loesungsansatz sein. Er wird aller-
> dings bei einem "kill -9" nicht helfen, da sich dieses auch durch ein "trap"
> Kommando in einem script meines Wissens nach nicht abfangen laesst ...
> Lass uns bitte wissen, ob es funktioniert hat.

Ich denke, dass es genau daran liegt. Ich teste das in den nächsten Tagen.

Jan

Jan Novak

unread,
Nov 25, 2020, 10:02:13 AM11/25/20
to
Am 25.11.20 um 12:23 schrieb Juergen Ilse:
> Hallo,
>
> Jan Novak <rep...@gmail.com> wrote:
>> Am 24.11.20 um 18:23 schrieb Stefan Reuther:
>>> Am 24.11.2020 um 10:43 schrieb Jan Novak:
>>> (Und wenn wir bei 'set' unterwegs sind: 'set -e' bricht das Skript ab,
>>> sobald ein Kommando fehlschlägt, z.B. das extern getötete rsync.)
>>
>> Verständnisfehler:
>> Nicht das rsync wird gekillt, sondern das Script, welches die rsync's
>> nacheinander starten würde.
>> Und genau dann passiert es, dass - obwohl das script bereits ge'kill't
>> wurde, der nachfolgende rsync des gekilltem scriptes dennoch aufgerufen
>> wird.
>
> Das glaube ich irgendwie nicht so ganz. Ein gekilltes script kann nichts
> mehr starten. Bist du sicher, dass du das richtige script gekillt hast?
> Ich ging davon aus, dass das script, von dem aus alles gestartet wird,
> weitere scripts mit den rsync-kommandos startet.

Nein. Das script ruft mehrere rsync befehle auf - keine weiteren
scripte. Die rsyncs werden alle nacheinander aufgerufen - und *nicht* in
den hintergrund geforkt. Somit läuft das script quasi so lange, bis der
letzte rsync Prozess beendet wird. Nach dem Killen des scriptes über
seine pid, bleibt immer ein rsync prozess am laufen. Kille ich den mit
killall erscheint meistens noch einer, welchen ich ebenfalls killen muss.
Für mich sieht es so aus, dass das Script alle rsync Befehle noch
nacheinander absendet, obwohl das eigentliche Script gar nicht mehr da ist.
Noch zu info: die Umgebung ist ein debian buster mit der bash shell.


Jan

Jan Novak

unread,
Nov 25, 2020, 10:06:01 AM11/25/20
to
Am 25.11.20 um 15:02 schrieb Helmut Waitzmann:
>> Killen des Scripts reißt den rsync mit weg
>
> Das allerdings stimmt nicht, jedenfalls nicht automatisch von vorne
> herein:  Ein Prozess, der aufgrund eines empfangenen Signals beendet
> wird, tötet seine Kinder nicht grundsätzlich, sondern lässt sie als
> Waisen zurück.
>
> Man könnte aber hergehen und dem Prozess einen Signalbehandler
> beispielsweise für das TERM‐, INT‐ und QUIT‐Signal verpassen: einen
> Signalbehandler, der dem Kind ein entsprechendes Signal schickt, dann
> den Signalbehandler auf SIG_DFL zurückstellt und ein entsprechendes
> Signal auch noch an sich selbst schickt.

Aha... das scheint hier der Fall zu sein.


> 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.


> Das ist bei modernen Shells in interaktiver Betriebsart der Fall, wenn
> das Skript als interaktives Kommando gestartet wird.

> Probiere das mit folgendem Shell‐Skript aus:
>
>   #!/bin/sh
>   exec ps -o pgid=Job-Gruppe -o pid=Prozessnummer -o args -p "$$"

Das heisst, ein set -m in obigem Beispiel würde nicht schaden, da das
Script vom cron gestartet wird?


Jan


Thomas Noll

unread,
Nov 25, 2020, 11:36:30 AM11/25/20
to
Doch. So wie du es machst funktioniert es nicht.
Man kann auf eine aktive PID ohne grep testen, einfach mit ps.
man ps(1)
Und außer dir hat niemand was von grep in /var/run geschrieben.



Helmut Waitzmann

unread,
Nov 25, 2020, 4:42:43 PM11/25/20
to
Juergen Ilse <ne...@usenet-verwaltung.de>:
>Helmut Waitzmann <nn.th...@xoxy.net> wrote:
>> Stefan Reuther <stefa...@arcor.de>:

>>>Killen des Scripts reißt den rsync mit weg
>>>

>> Das allerdings stimmt nicht, jedenfalls nicht automatisch von
>> vorne herein:  Ein Prozess, der aufgrund eines empfangenen
>> Signals beendet wird, tötet seine Kinder nicht grundsätzlich,
>> sondern lässt sie als Waisen zurück. 
>
>Die Children bekommen ein Signal, sofern der Parent sie nicht
>bereits hat "verwaisen" lassen (z.B. mittels "nohup" oder in der
>bash mittels "disown" von Hintergrundprozessen).

Das ist eine Spezialität des Bash, wenn er interaktiv läuft, siehe
Handbuch bash(1) und kein Standardverhalten des Linux‐Kerns:

The shell exits by default upon receipt of a SIGHUP. Before
exiting, an interactive shell resends the SIGHUP to all jobs,
running or stopped. Stopped jobs are sent SIGCONT to ensure that
they receive the SIGHUP. To prevent the shell from sending the
signal to a particular job, it should be removed from the jobs
table with the disown builtin (see SHELL BUILTIN COMMANDS below)
or marked to not receive SIGHUP using disown -h.

If the huponexit shell option has been set with shopt, bash
sends a SIGHUP to all jobs when an interactive login shell
exits.


>Ich bin mir im Moment allerdings nicht sicher, welches Signal die
>Children bekommen (moeglicherweise ein HUP, aber die
>Default-Reaktion darauf sollte eigentlich auch "Selbstbeendigung"
>sein).
>
>Gerade noch mal schnell nesucht: Ja, es ist SIGHUP:
>
>-----------------------
>Are you ignoring SIGHUP or daemonizing by escaping the session
>group ? If so, your process won’t be killed with the others. Make
>sure you aren’t doing neither.
>
>If your process is somehow being created in another process group
>for some unavoidable reason, then you’ll need to use non portable
>Linux extensions to detect that the parent died:
>
>prctl(PR_GET_PDEATHSIG, &sig);
>signal(sig, on_parent_killed);
>-----------------------
>Quelle:
>https://www.reddit.com/r/C_Programming/comments/jykfyx/program_not_dying_when_the_parent_dies/

Ich schlage vor, Du probierst es lieber aus, als diesem Forum zu
glauben, bei dem die Ausgangslage nicht genau ermittelt wurde, und
bei dem auf linux‐spezifische Mittel zurückgegriffen wird, die im
Shell nicht verfügbar sind, weil es keine entsprechenden
Builtin‐Commands dafür gibt. 

Nimm Dir dazu ein Terminal mit einem darin laufenden interaktiven
Shell her und starte darin die folgenden Kommandos:

# Schalte im Terminaltreiber das TTOU‐Signal ab, damit
# Hintergrundprozesse aufs Terminal schreiben duerfen:
stty -tostop

sh -c -- '
{ sleep -- 2 &&
printf %s\\n '\''Ich bin das Kind.'\''
} &
printf %s\\n '\''Ich bin der Vater.'\''
kill -s TERM -- "$$"' sh

Deiner Meinung nach hätte sich der Kindprozess (spätestens,
nachdem das Sleep‐Kommando beendet war) mitbeenden sollen, wenn
der Vaterprozess, vom Signal getroffen, beendet wird.  Trotzdem
erhältst Du nach 2 Sekunden noch eine Ausgabe.  Wie erklärst Du
Dir das?

>Es ist fuer ein script auch nicht notwendig, sich selbst zu
>killen, wenn es sich auch ganz einfach mit "exit" mit weniger
>Aufwand selbst beenden kann ...

Du hast den Witz am Selbstmord durch Signalverschickung an sich
selbst nicht verstanden:  Auf diese Weise kommt das Skript genau
so – also mit genau dem exit status – zu Ende, als wenn es von
vorne herein keinen Signalbehandler eingerichtet gehabt hätte, und
der Prozess, der es gestartet hat (beispielsweise Cron), kann das
bemerken und beispielsweise die Fehlermeldung «wurde durch das
TERM‐Signal beendet» per E‐Mail verschicken. 

Das ist für Prozesse, die bei Empfang eines bestimmten Signals
zunächst noch etwas aufräumen wollen, danach aber der Intention
des Signals folgen wollen, eigentlich best practice, nach dem
Aufräumen den Signalbehandler auf SIG_DFL zurückzustellen und sich
das Signal selbst zu schicken. 

--
Hat man erst verstanden, wie Unix funktioniert, ist auch
das Shell-Handbuch kein Buch mit sieben Siegeln mehr.

Helmut Waitzmann

unread,
Nov 25, 2020, 4:53:35 PM11/25/20
to
Thomas Noll <-_tn...@web.de>:

>Man kann auf eine aktive PID ohne grep testen, einfach mit ps.

Noch einfacher mit «kill»:

kill -s 0 -- "$pid"

Jan Novak

unread,
Nov 26, 2020, 1:58:21 AM11/26/20
to
Am 25.11.20 um 17:36 schrieb Thomas Noll:
auch wenn dein Kommentar nichts mit meine eigentlichen Problem zu tuin hat:

Was ist daran falsch

[ "$(ps ax|grep $pid|grep -v ps)" ]

die pid aus einer Datei zu lesen (mit cat Datei, nicht grep)und diese
dann in der Prozess Liste zu suchen?

Jan

Jan Novak

unread,
Nov 26, 2020, 2:03:05 AM11/26/20
to
Am 25.11.20 um 22:53 schrieb Helmut Waitzmann:
> Thomas Noll <-_tn...@web.de>:
>
>> Man kann auf eine aktive PID ohne grep testen, einfach mit ps.
>
> Noch einfacher mit «kill»:
>
> kill -s 0 -- "$pid"
>

Dazu musst du die PID aber kennen.
Und diese habe ich aus einer pid Datei aus /var/run/datei mit cat gelsen.
Dann mit grep in der Prozess Liste danach gesucht.
Der Vorwurf von Stefan war, ich würde wild in /var/run greppen.
Das ist nicht korrekt.

Jan

Thomas Noll

unread,
Nov 26, 2020, 2:55:53 AM11/26/20
to
Am Thu, 26 Nov 2020 07:58:20 +0100 schrieb Jan Novak:

> Am 25.11.20 um 17:36 schrieb Thomas Noll:
>> Am Wed, 25 Nov 2020 15:55:18 +0100 schrieb Jan Novak:
>>
>>> Am 25.11.20 um 12:40 schrieb Stefan Wiens:
>>>>> "Blauäugigem herum-grep'en" ;-)
>>>>> Scherzkeks. Niemand greppt blauäugig in /var/run...
>>>>> [...]
>>>>
>>>> ,----[ <rpinep$4t1$1...@gwaiyur.mb-net.net> ]
>>>> | if [ "$pid" ] && [ "$(ps ax|grep $pid|grep -v ps)" ] ; then
>>>> `----
>>>>
>>>> Der Suchstring "$pid" darf also sowohl als Teil einer anderen Process-ID
>>>> wie auch in den Argumentlisten aller Prozesse vorkommen.
>>>
>>> Ja... deswegen greppt dennoch keiner in /var/run - nur in der Prozess
>>> Liste - und dagegen ist sicher nichts einzuwenden.
>>
>> Doch. So wie du es machst funktioniert es nicht.
>> Man kann auf eine aktive PID ohne grep testen, einfach mit ps.
>> man ps(1)
>> Und außer dir hat niemand was von grep in /var/run geschrieben.
>
>
> auch wenn dein Kommentar nichts mit meine eigentlichen Problem zu tun hat:

Zynisch gesagt: doch.

>
> Was ist daran falsch
>
> [ "$(ps ax|grep $pid|grep -v ps)" ]
>
> die pid aus einer Datei zu lesen (mit cat Datei, nicht grep)und diese
> dann in der Prozess Liste zu suchen?

Etwas hat Stefan dir doch schon geschrieben.
additional hint: probier das mal mit pid=0

Die eigentliche Frage müsste lauten:
Was ist daran richtig?

Erläuter doch z.B. mal deine Absicht hinter grep -v ps...




Rupert Haselbeck

unread,
Nov 26, 2020, 4:50:09 AM11/26/20
to
Jan Novak schrieb:

> Was ist daran falsch
>
> [ "$(ps ax|grep $pid|grep -v ps)" ]
>
> die pid aus einer Datei zu lesen (mit cat Datei, nicht grep)und diese
> dann in der Prozess Liste zu suchen?

Dieser Einzeiler findet in der Prozeßliste etwas zu viel. Stell dir vor, es
gibt beispielsweise einen Prozeß mit PID 823 und es gibt einen Prozeß mit
PID 18234. Es genügt für eine Falschausgabe natürlich auch, wenn sich die
Zeichenfolge der gesuchten PID in einem anderen Teil der Ausgabe von ps
findet.
Beispiel:
| ps -ax | grep 72
erzeugt hier gerade 44 Ausgabezeilen mit allem möglichen Zeug, aber nicht
einer PID mit 72.

Beschränkt man die Ausgabe von ps auf die PID, dann ist das immer noch wenig
hilfreich:
| ps -ax -o pid | grep 72
erzeugt hier gerade:
| 72
| 722
| 725
| 1072
| 1272
| 1372
| 2672
| 2724

Wenn du nur wissen willst, ob ein Prozeß mit bekannter PID in der ps-Ausgabe
zu finden ist, dann reduziere die Ausgabe von ps entsprechend oder, besser,
folge dem Hinweis zur Verwendung des kill-Kommandos für diesen Zweck. Dann
kannst du dir auch den, hier ohnehin wenig hilfreichen, zusätzlichen grep-
Aufruf zum Wegwerfen des "grep" selbst sparen

MfG
Rupert

Jan Novak

unread,
Nov 26, 2020, 5:51:36 AM11/26/20
to
Am 26.11.20 um 10:50 schrieb Rupert Haselbeck:
> Beschränkt man die Ausgabe von ps auf die PID, dann ist das immer noch wenig
> hilfreich:
> | ps -ax -o pid | grep 72
> erzeugt hier gerade:
> | 72
> | 722
> | 725
> | 1072
> | 1272
> | 1372
> | 2672
> | 2724
>
> Wenn du nur wissen willst, ob ein Prozeß mit bekannter PID in der ps-Ausgabe
> zu finden ist, dann reduziere die Ausgabe von ps entsprechend oder, besser,
> folge dem Hinweis zur Verwendung des kill-Kommandos für diesen Zweck. Dann
> kannst du dir auch den, hier ohnehin wenig hilfreichen, zusätzlichen grep-
> Aufruf zum Wegwerfen des "grep" selbst sparen



Ja, nachvollziehbar. Auf dem besagtem System läuft zunächst "nur" das
Basissystem und der rsync. Somit ist der Fall unwahrscheinlich - aber -
wie du korrekt schreibst, nicht unmöglich und somit werde ich es anders
abfragen (vermutlich mit dem direkten kill).

Mir ging es um die Aussage, ich würde in "/var/run/ wild herum greppen",
was nicht korrekt ist. Dass ich mit meinem grep auf der Prozessliste
auch Ausgaben bekommen könnte, die gar nicht gewünscht sind (so wie von
dir oben beschrieben), ist ein ganz anderes Thema.
Danke für den Hinweis.

Jan

Jan Novak

unread,
Nov 26, 2020, 6:03:56 AM11/26/20
to
Am 25.11.20 um 22:42 schrieb Helmut Waitzmann:

> Ich schlage vor, Du probierst es lieber aus, als diesem Forum zu
> glauben,
...
>  # Schalte im Terminaltreiber das TTOU‐Signal ab, damit
>  # Hintergrundprozesse aufs Terminal schreiben duerfen:
>  stty -tostop
>
>  sh -c -- '
>    { sleep -- 2 &&
>      printf %s\\n '\''Ich bin das Kind.'\''
>    } &
>    printf %s\\n '\''Ich bin der Vater.'\''
>    kill -s TERM -- "$$"' sh
>
> Deiner Meinung nach hätte sich der Kindprozess (spätestens, nachdem das
> Sleep‐Kommando beendet war) mitbeenden sollen, wenn der Vaterprozess,
> vom Signal getroffen, beendet wird.  Trotzdem erhältst Du nach 2
> Sekunden noch eine Ausgabe.  Wie erklärst Du Dir das?

Korrekt, kann ich hier genauso nachvollziehen.


>> Es ist fuer ein script auch nicht notwendig, sich selbst zu killen,
>> wenn es sich auch ganz einfach mit "exit" mit weniger Aufwand selbst
>> beenden kann ...

Mein Wunsch ist es, dass dieses Script gestoppt werden soll, wenn es
manuell notwendig ist - also jemand entscheidet, die rsync's in diesem
script sollen "jetzt" beenden werden. Somit müsste man dem Script die
Info senden, es soll sich und alle aktuell gestarteten rsync (sub- ?)
Prozesse beenden *und* keinen weiteren mehr aufrufen sofern noch einer
folgen würde.

Jan

Jan Novak

unread,
Nov 26, 2020, 6:11:40 AM11/26/20
to
Am 25.11.20 um 15:02 schrieb Helmut Waitzmann:
>
> In nicht‐interaktiver Betriebsart machen das Shells (zumindest ohne
> besondere Aufforderung dazu) aber nicht.  (Aber siehe dazu unten «set -m».)
>
> Probiere das mit folgendem Shell‐Skript aus:
>
>   #!/bin/sh
>   exec ps -o pgid=Job-Gruppe -o pid=Prozessnummer -o args -p "$$"
>
> Falls das Skript in einer eigenen Job‐Gruppe läuft, enthalten die
> Spalten «Job-Gruppe» und «Prozessnummer» dieselbe Zahl; anderenfalls nicht.


Ich bekomme das hier raus
b-Gruppe Prozessnummer COMMAND
12299 12299 ps -o pgid=Job-Gruppe -o pid=Prozessnummer -o
args -p 12299

und die PID's sind imme rgleich, egal ob "set -m" gesetzt ist oder nicht.


Jan

Stefan Wiens

unread,
Nov 26, 2020, 8:10:33 AM11/26/20
to
Nirgendwo habe ich dir vorgeworfen, in /var/run zu greppen:

,----[ <871rgjn...@eswe.dd-dns.de> ]
| Zweitens hat dein Script offenbar Write-Permissions nach /var/run. Da
| sollte man mit dem blauäugigen herum-grep(1)-en in der Ausgabe von ps(1)
| vorsichtig sein.
`----

--
Stefan

Helmut Waitzmann

unread,
Nov 26, 2020, 8:56:51 PM11/26/20
to
Jan Novak <rep...@gmail.com>:
>Am 25.11.20 um 15:02 schrieb Helmut Waitzmann:

>> Ein Prozess, der aufgrund eines empfangenen Signals beendet
>> wird, tötet seine Kinder nicht grundsätzlich, sondern lässt sie
>> als Waisen zurück.
>>
>> Man könnte aber hergehen und dem Prozess einen Signalbehandler
>> beispielsweise für das TERM‐, INT‐ und QUIT‐Signal verpassen:
>> einen Signalbehandler, der dem Kind ein entsprechendes Signal
>> schickt, dann den Signalbehandler auf SIG_DFL zurückstellt und
>> ein entsprechendes Signal auch noch an sich selbst schickt.
>
>Aha... das scheint hier der Fall zu sein.
>

Falls Du das auf den ersten Abschnitt bezogen haben willst, stimme
ich zu. 

Das im zweiten Abschnitt Beschriebene geschieht nur dann, wenn man
es im Skript programmierst; von selbst geschieht es nicht:

for signal in HUP INT QUIT TERM PIPE
do
# Richte den Signalbehandler fuer das Signal "$signal" ein:
trap -- 'kill -s '"$signal"' -- '"$pid"'
trap -- - '"$signal"'
kill -s '"$signal"' -- '"$$"
done

Jan Novak

unread,
Nov 27, 2020, 2:28:22 AM11/27/20
to
Am 26.11.20 um 08:55 schrieb Thomas Noll:
>> auch wenn dein Kommentar nichts mit meine eigentlichen Problem zu tun hat:
>
> Zynisch gesagt: doch.

Dann sei mal nicht zynisch!


>>
>> Was ist daran falsch
>>
>> [ "$(ps ax|grep $pid|grep -v ps)" ]
>>
>> die pid aus einer Datei zu lesen (mit cat Datei, nicht grep)und diese
>> dann in der Prozess Liste zu suchen?
>
> Etwas hat Stefan dir doch schon geschrieben.
> additional hint: probier das mal mit pid=0

*WARUM* sollte ich das tun?
Pid war, ist und wird nie 0 sein!


> Die eigentliche Frage müsste lauten:
> Was ist daran richtig?
>
> Erläuter doch z.B. mal deine Absicht hinter grep -v ps...

du müsstest doch wiessen, was "grep -v ps" bedeutet, oder nicht?


Jan

Jan Novak

unread,
Nov 27, 2020, 2:29:54 AM11/27/20
to
Am 26.11.20 um 14:10 schrieb Stefan Wiens:
> Nirgendwo habe ich dir vorgeworfen, in /var/run zu greppen:
>
> ,----[ <871rgjn...@eswe.dd-dns.de> ]
> | Zweitens hat dein Script offenbar Write-Permissions nach /var/run. Da
> | sollte man mit dem blauäugigen herum-grep(1)-en in der Ausgabe von ps(1)
> | vorsichtig sein.
> `----
>

Dann haben wir unterschiedliche Auffassungen von Meinung und
geschriebenen Wort.
Der Einfachheit halber sollten wir "dieses" Thema hier aber auf sich
beruhen lassen.

Jan

Juergen Ilse

unread,
Nov 27, 2020, 4:25:51 AM11/27/20
to
Hallo,

Jan Novak <rep...@gmail.com> wrote:
Zum einen kann dir das erheblich mehr als das Kommando "ps" herausfischen
("ps" kommt z.B. auch im Wort "Schnaps" vor, und wie kannst du sicher sein,
dass dieses Wort oder ein andrres "ps" enthaltendes Wort irgendwo in einem
Kommandozeilenargument vorkommt?), zum anderen ist es ohnehin eine daemliche
Methode, im Nachhinein den suchenden Prozess, der sich selbst findet, wieder
aus der Liste der Funde ausschliesen zu wollen: es ist fehlertraeechtig und
unnoetig.

Statt dessen sollte man einen Suchbegriff verwenden, der moeglichst genau die
spezifischen Teile des gesuchten Prozesses aber nicht sich selbst matched.

Um z.B. kein das "grep" Kommando nicht selbst herausfischen zu muessen,
hilft es, einen Suchbegriff zu verwenden, der sich nicht sebst matched.
Sucht man nach "ps", koennte man als Sucbhbegriff z.B. die regular expression
"[p]s" verwenden. Um nicht mit "ps" auch alle Worte zu finden, in denen "ps"
mittendrin als Zeichenkette vorkommt, koennte man nach "[ /][p]s " suchen.
Dam,it hat man zwar immer noch nicht die Faelle erschlkagen, in denen "ps"
als separates Kommandozeilenargument vorkommt, aber zumindest erhaelt man
schon viel weniger "unerwuenschten Beifang" ...
Die Methode, im nachhinein den Prozesse herausfiltern zu wollen, die man
zur Suche nach den Prozessen verwendet hat, halte ich persoenlich eher fuer
*sehr* schlechten Stil, weil man sich potentielle aber vermeidbare Probleme
einhandelt. Wenn man den ganzen Schmuh nicht selbst mittels "grep" aus der
Prozessliste herausfischen will, sollte man auch ueber Kommandos wie "pgrep"
und "pkill" nachdenken, die einem eine Menge der potentiellen Probleme des
"selbstheraussuchens und ausschneidens der PID" vom Hals schafft.

Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)
matched

Helmut Waitzmann

unread,
Nov 27, 2020, 11:45:59 AM11/27/20
to
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. 

Jan Novak

unread,
Dec 1, 2020, 5:57:59 AM12/1/20
to
Am 27.11.20 um 17:45 schrieb Helmut Waitzmann:
> Ganz kurz:
(... sehr ausführlich)

Vielen Dank für die Aufklärung (nicht ironisch gemeint).

(... sehr interessante Aufzählungen)


>> Das heisst, ein set -m in obigem Beispiel würde nicht schaden, da das
>> Script vom cron gestartet wird?

korrekt - also dann, wenn es abschließend laufen wird.

>
> Ja.  Dazu müsste im Crontab etwa folgendes stehen:
>
>   set -m && hier_der_Aufruf_vom_Skript

Ahh... ich dachte, das "set -m" muss im Script stehen.

> 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.

kann ich hier (auch unter debian buster) nachvollziehen.

> Es kommt also darauf an, welchem Shell die im crontab enthaltenen
> Kommandozeilen zur Ausführung übergeben werden.

In der Regel /bin/bash.

Ich muss jetzt erstmal aus deinen Ausführungen das gewünschte
extrahieren und dann testen.

Nochmals, herzlichen Dank.


Jan

Helmut Waitzmann

unread,
Dec 1, 2020, 4:48:57 PM12/1/20
to
Jan Novak <rep...@gmail.com>:
>Am 27.11.20 um 17:45 schrieb Helmut Waitzmann:

>>> Das heisst, ein set -m in obigem Beispiel würde nicht schaden,
>>> da das Script vom cron gestartet wird?
>
>korrekt - also dann, wenn es abschließend laufen wird.
>
>>
>> Ja.  Dazu müsste im Crontab etwa folgendes stehen:
>>
>>
>>   set -m && hier_der_Aufruf_vom_Skript
>
>Ahh... ich dachte, das "set -m" muss im Script stehen.
>

Das Ziel soll ja sein, dass nicht das Skript seine «rsync»‐Aufrufe
als je eigenes Job startet, sondern, dass der Crontab‐Shell das
Skript als eigenes Job startet, damit man ein Signal an das
komplette Job, also das Skript mitsamt seinen
«rsync»‐Unterprozessen schicken kann und so alle Prozesse auf
einen Sitz erreicht.  Also muss das «set -m» nicht im Skript
sondern dort stehen, wo das Skript aufgerufen wird. 

Das Schicken eines Signals an ein ganzes Job (also eine
Prozessgruppe) wird im Systemaufruf «kill» so bewerkstelligt, dass
das Negative der Prozessnummer des Prozessgruppenführers angegeben
wird.  Und so hält es auch das «kill»‐Kommando, das nicht viel
mehr als eine einfache Verpackung des Systemaufrufs ist. 

Das in den Shell eingebaute «kill»‐Kommando bietet außerdem an,
die vom Shell vergebenen Job‐Nummern (also die Bezeichnungen «%1»,
«%2», …, «%+» und «%-», siehe im Shell‐Handbuch) anstelle der
Prozessnummern entgegenzunehmen. 

Jan Novak

unread,
Dec 3, 2020, 1:27:10 AM12/3/20
to
Am 01.12.20 um 22:33 schrieb Helmut Waitzmann:
> Jan Novak <rep...@gmail.com>:
>> Am 27.11.20 um 17:45 schrieb Helmut Waitzmann:
>
>>>> Das heisst, ein set -m in obigem Beispiel würde nicht schaden, da
>>>> das Script vom cron gestartet wird?
>>
>> korrekt - also dann, wenn es abschließend  laufen wird.
>>>
>>> Ja.  Dazu müsste im Crontab etwa folgendes stehen:
>>>
>>>    set -m && hier_der_Aufruf_vom_Skript
>>
>> Ahh... ich dachte, das "set -m" muss im Script stehen.
>
> Das Ziel soll ja sein, dass nicht das Skript seine «rsync»‐Aufrufe als
> je eigenes Job startet, sondern, dass der Crontab‐Shell das Skript als
> eigenes Job startet, damit man ein Signal an das komplette Job, also das
> Skript mitsamt seinen «rsync»‐Unterprozessen schicken kann und so alle
> Prozesse auf einen Sitz erreicht.  Also muss das «set -m» nicht im
> Skript sondern dort stehen, wo das Skript aufgerufen wird.


ahh... verstehe. Das macht es jetzt verständlich.
Vielen Dank für deine Ausführungen.


Jan
0 new messages