PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bash: Wie Signal-Handling?



Linus
07-09-2007, 00:09
Ich habe Bash-Skripte die in einer Endlosschleife etwas machen, beispielsweise eine DSL-Verbindung überprüfen.
Nun habe ich aber Prozesse, beispielsweise einen Prozess der die DSL-Verbindung terminiert damit nicht der Provider irgendwann eine Zwangstrennung macht, und so ein Prozess soll dem Skript mit der Endlosschleife eine Nachricht per Signal schicken, das vom Skript ja per trap eingelesen werden kann.
Wie aber kann ich das im Skript nutzen, also beispielsweise sowas wie ein longjmp (non-local goto) zu einer bestimmten Zeile im Skript? :confused:

Die Bash kennt ja kein longjmp, aber genau sowas bräuchte ich.
Welche Workarounds gibt's dafür? :confused:

peschmae
07-09-2007, 06:11
Bash kennt Funktionen - auch wenn das z.T. etwas Umdenken erfordert kann man damit das meiste goto-Zeugs ersetzen :)

MfG Peschmä

BLUESCREEN3D
07-09-2007, 13:48
Du kannst, wie von peschmae vorgeschlagen, eine Funktion nutzen und musst dann nur noch trap den Funktionsnamen mitteilen:

trap deine_funktion irgendein_signal
Dann läuft die Endlosschleife aber weiter, nachdem die Funktion abgearbeitet wurde (es sei denn du hast ein exit drin).

Oder, falls du willst, dass die Endlosschleife durch das Signal beendet wird, könntest du das lösen, indem du die Schleife etwas änderst:

wait_in_loop=1

trap wait_in_loop=0 irgendein_signal

while [ $wait_in_loop -eq 1 ]; do
#dein schleifeninhalt
done

#hier gehts ab dem signal weiter

Linus
07-09-2007, 18:04
Hm, dann bleibt nur das das Skript etwas in Config-Files schreibt, sich selbst terminiert und per inittab neu gestartet wird, denn in jeder zweiten Zeile der Endlosschleife ein Flag abzufragen und ein sleep 30 in eine aufgeblähte Schleife aufzublasen wäre ein gewaltiges Rumgefrickel, das man z. B. mit Posix-Threads nie nötig hat.

jan61
07-09-2007, 20:03
Hm, dann bleibt nur das das Skript etwas in Config-Files schreibt, sich selbst terminiert und per inittab neu gestartet wird, denn in jeder zweiten Zeile der Endlosschleife ein Flag abzufragen und ein sleep 30 in eine aufgeblähte Schleife aufzublasen wäre ein gewaltiges Rumgefrickel, das man z. B. mit Posix-Threads nie nötig hat.

Das verstehe ich nicht. Wieso willst Du in jede 2. Zeile der Schleife eine Abfrage stecken? Nimm trap mit einem Funktionsaufruf, der die nötigen Arbeiten verrichtet. Und außerdem dachte ich, Du hättest eh eine Endlos-Schleife im Script?

Jan

Linus
08-09-2007, 10:10
Das verstehe ich nicht. Wieso willst Du in jede 2. Zeile der Schleife eine Abfrage stecken? Nimm trap mit einem Funktionsaufruf, der die nötigen Arbeiten verrichtet. Und außerdem dachte ich, Du hättest eh eine Endlos-Schleife im Script?

Jan

Die zu verrichtende Arbeit wäre an eine ganz bestimmte Stelle in der Endlosschleife zu springen und das kann ja keine Bash-Funktion.

bfit
08-09-2007, 15:40
In der Trap-funktion Steuervariable setzen und continue für die Endlosschleife.

jan61
08-09-2007, 18:42
Ich weiß auch nicht, was daran so umständlich ist:
jan@jack:~/tmp> cat loop_signal.sh
#! /bin/bash

export CTRL=0

trap "CTRL=`expr $CTRL + 1`" 1 2 3 15

while true; do
echo "Schleifenbeginn" `date +%S`
sleep 5
if test $CTRL -eq 0; then
echo "CTRL = 0"
else
echo "CTRL = $CTRL"
CTRL=0
continue
fi
echo "Schleifenende" `date +%S`
done
jan@jack:~/tmp> ./loop_signal.sh
Schleifenbeginn 09
CTRL = 0
Schleifenende 14
Schleifenbeginn 14
CTRL = 1
Schleifenbeginn 17
CTRL = 1
Schleifenbeginn 18
CTRL = 1
Schleifenbeginn 18
CTRL = 0
Schleifenende 23
Eine andere Variante, die Dir hier schon vorgeschlagen wurde (halte ich auch für sauberer): Bau Dir eine oder mehrere Funktionen, die das tun, was in der Schleife zu erledigen ist. Den Funktionen kannst Du ja beliebige Parameter (u. a. auch einen für die Erkennung, ob ein Signal empfangen wurde) mitgeben und innerhalb der Funktion auswerten.

Jan