Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
Shell-Programmierung von Jürgen Wolf
Einführung, Praxis, Referenz
Buch: Shell-Programmierung

Shell-Programmierung
782 S., mit CD, 44,90 Euro
Rheinwerk Computing
ISBN 3-89842-683-1
gp Kapitel 8 Rund um die Ausführung von Scripts und Prozessen
  gp 8.1 Prozessprioritäten
  gp 8.2 Warten auf andere Prozesse
  gp 8.3 Hintergrundprozess wieder hervorholen
  gp 8.4 Hintergrundprozess schützen
  gp 8.5 Subshells
  gp 8.6 Mehrere Scripts verbinden und ausführen (Kommunikation zwischen Scripts)
    gp 8.6.1 Datenübergabe zwischen Scripts
    gp 8.6.2 Rückgabe von Daten an andere Scripts
    gp 8.6.3 Scripts synchronisieren
  gp 8.7 Jobverwaltung
  gp 8.8 Shellscripts zeitgesteuert ausführen
  gp 8.9 Startprozess- und Profildaten der Shell
    gp 8.9.1 Arten von Initialisierungsdateien
    gp 8.9.2 Ausführen von Profildateien beim Start einer Login-Shell
    gp 8.9.3 Ausführen von Profildateien beim Start einer Nicht-Login-Shell (Bash und Korn-Shell)
    gp 8.9.4 Zusammenfassung alle Profil- und Startup-Dateien
  gp 8.10 Ein Shellscript bei der Ausführung
    gp 8.10.1 Syntaxüberprüfung
    gp 8.10.2 Expansionen
    gp 8.10.3 Kommandos
  gp 8.11 Shellscripts optimieren


Rheinwerk Computing

8.6 Mehrere Scripts verbinden und ausführen (Kommunikation zwischen Scriptsdowntop

Im Laufe der Zeit werden Sie eine Menge Scripts schreiben und sammeln. Häufig will man hierbei gern das ein oder andere von einem anderen Script verwenden. Entweder man verwendet dann »Copy & Paste« oder man ruft das Script aus dem Haupt-Script auf. Da es nicht immer ganz einfach ist, Scripts miteinander zu verbinden und die Datenübertragung zu behandeln, soll im folgenden Abschnitt ein wenig genauer darauf eingegangen werden.


Rheinwerk Computing

8.6.1 Datenübergabe zwischen Scripts  downtop

Zur Übergabe von Daten an das neue Script gibt es mehrere gängige Möglichkeiten. Eine einfache ist das Exportieren der Daten, bevor das zweite Script aufgerufen wird. Der Einfachheit halber werden wir hier von »script1« und »script2« reden und diese in der Praxis auch mehrmals verwenden. Hier die Möglichkeit, Daten an ein anderes Script mittels export zu übergeben:

# Name script1
a=1
b=2
c=3
export a b c
./script2

Jetzt das script2:

# Name : script2
echo "$0 : a=$a; b=$b; c=$c"

Die Datenübergabe bei der Ausführung:

you@host > ./script1
./script2 : a=1; b=2; c=3

Eine weitere Möglichkeit ist die Übergabe als Argument, wie Sie dies von der Kommandozeile her kennen. Dem aufgerufenen Script stehen dann die einzelnen Variablen mit den Positionsparametern $1 bis $9 bzw. ${n} zur Verfügung. Auch hierzu wieder die beiden Scripts.

# Name script1
a=1
b=2
c=3
./script2 $a $b $c

Und script2:

# Name : script2
echo "$0 : a=$1; b=$2; c=$3"

Die Ausführung entspricht der im Beispiel mittels export.

Sobald allerdings der Umfang der Daten zunimmt, werden Sie mit diesen beiden Möglichkeiten recht schnell an Grenzen stoßen. Hierzu würde sich die Verwendung einer temporären Datei anbieten: Ein Prozess schreibt etwas in die Datei und ein anderer liest wieder daraus.

# Name script1
IFS='\n'
for var in `ls -l`
do
   echo $var
done > file.tmp
./script2

Das »script2«:

# Name : script2
while read line
do
   echo $line
done < file.tmp

Im Beispiel liest »script1« zeilenweise von `ls –l` ein und lenkt die Standardausgabe von echo auf die temporäre Datei file.tmp um. Am Ende wird »script2« gestartet. »script2« wiederum liest zeilenweise über eine Umlenkung von der Datei file.tmp ein und gibt dies auch zeilenweise mit echo auf dem Bildschirm aus. Das Ganze könnten Sie auch ohne eine temporäre Datei erledigen, indem Sie beide Scripts mit einer Pipe starten, da hier ja ein Script die Daten auf die Standardausgabe ausgibt und ein anderes Script die Daten von der Standardeingabe erhält:

you@host > ./script1 | ./script2

Damit dies auch funktioniert, müssen Sie in den beiden Scripts lediglich die Umlenkungen und den Scriptaufruf entfernen. Somit sieht »script1« wie folgt aus:

# Name script1
IFS='\n'
for var in `ls -l`
do
   echo $var
done

Und gleiches Bild bei »script2«:

# Name : script2
while read line
do
   echo $line
done

Rheinwerk Computing

8.6.2 Rückgabe von Daten an andere Scripts  downtop

Der gängigste Weg, Daten aus einem Script an ein anderes zurückzugeben, ist eigentlich die Kommando-Substitution. Ein simples Beispiel:

# Name : script1
var=`./script2`
echo "var=$var"

Und das »script2«:

# Name : script2
echo "Hallo script1"

»script1« bei der Ausführung:

you@host > ./script1
var=Hallo script1

Gleiches funktioniert auch, wenn das Script mehrere Werte zurückgibt. Hierzu würde sich etwa das Aufsplitten der Rückgabe mittels set anbieten:

# Name script1
var=`./script2`
set $var
echo "$1; $2; $3"

Jetzt noch »script2«:

# Name : script2
var1=wert1
var2=wert2
var3=wert3
echo $var1 $var2 $var3

»script1« bei der Ausführung:

you@host > ./script1
wert1; wert2; wert3

Sollten Sie allerdings nicht wissen, wie viele Werte ein Script zurückgibt, können Sie das Ganze auch in einer Schleife abarbeiten:

# Name script1
var=`./script2`
i=1
for wert in $var
do
   echo "$i: $wert"
   i=`expr $i + 1`
done

Trotzdem sollte man auch bedenken, dass mit steigendem Umfang der anfallenden Datenmenge auch hier nicht so vorgegangen werden kann. In einer Variablen Daten von mehreren Megabytes zu speichern, ist nicht mehr sehr sinnvoll. Hier bleibt Ihnen nur noch die Alternative, eine temporäre Datei zu verwenden, wie Sie sie schon in Abschnitt 8.6.2 verwendet haben. Allerdings besteht auch hier ein Problem, wenn bspw. »script1« die Daten aus der temporären Datei lesen will, die »script2« hineinschreibt, aber »script2« die Daten nur scheibchenweise oder eben permanent in die temporäre Datei hineinschreibt. Dann wäre eine Lösung mit einer Pipe die bessere Alternative. Auch hierzu müssten Sie nur »script1« verändern:

# Name script1
./script2 | while read wert
do
   for val in $wert
   do
      echo "$val"
   done
done

Named Pipe

Ein weiteres sehr interessantes Mittel zur Datenübertragung zwischen mehreren Scripts haben Sie in Abschnitt 5.6 mit der Named Pipe (FIFOs) kennen gelernt. Der Vor- bzw. auch Nachteil (je nach Anwendungsfall) ist hierbei, dass ein Prozess, der etwas in eine Pipe schreibt, so lange blockiert wird, bis auf der anderen Seite ein Prozess ist, der etwas daraus liest. Umgekehrt natürlich derselbe Fall. Ein typischer Anwendungsfall wäre ein so genannter Server, der Daten von beliebigen Clients, die ihm etwas durch die Pipe schicken, einliest:

# Name: PipeServer
mknod meine_pipe p
while true
do
   # Wartet auf Daten aus der Pipe
   read zeile < meine_pipe
   echo $zeile
done

Statt einer Ausgabe auf dem Bildschirm können Sie mit diesem Server munter Daten von beliebig vielen anderen Scripts sammeln. Der Vorteil: Die anderen Scripts, die Daten in diese Pipe schicken, werden nicht blockiert, weil immer auf der anderen Seite des Rohrs der Server »PipeServer« darauf wartet.


Rheinwerk Computing

8.6.3 Scripts synchronisieren  toptop

Spätestens, wenn Ihre Scripts dauerhaft laufen sollen, benötigen Sie eine Prozess-Synchronisation. Fallen hierbei dann mehr als zwei Scripts an und wird außerdem in eine Datei geschrieben und gelesen, haben Sie schnell Datensalat. Eine recht einfache und zuverlässige Synchronisation zweier oder auch mehrerer Scripts erreichen Sie bspw. mit den Signalen. Richten Sie hierzu einfach einen Signalhandler mit trap ein, der auf ein bestimmtes Signal reagiert und ein weiteres Script aufruft. Bspw.:

# Name: script1
trap './script2' SIGUSR1
while true
do
   echo "Lese Daten ..."
   sleep 5
   echo "Starte script2 ..."
   kill -SIGUSR1 $$
done

Und das »script2«:

# Name: script2
trap './script1' SIGUSR2
while true
do
   echo "Schreibe Daten ..."
   sleep 5
   echo "Starte script1 ..."
   kill -SIGUSR2 $$
done

Die Scripts bei der Ausführung:

you@host > ./script1
Lese Daten ...
Starte script2 ...
Schreibe Daten ...
Starte script1 ...
Lese Daten ...
Starte script2 ...
Schreibe Daten ...
Starte script1 ...
Lese Daten ...
Starte script2 ...
Schreibe Daten ...

Eine weitere Möglichkeit zur Synchronisation von Scripts besteht darin, eine Datei zu verwenden. Hierbei wird in einer Endlosschleife immer überprüft, ob eine bestimmte Bedingung erfüllt ist. Je nach Bedingung wird dann ein entsprechendes Script ausgeführt. Hierzu werden alle Scripts aus einem Haupt-Script gesteuert. Was Sie dabei alles überprüfen, bleibt Ihnen überlassen. Häufig verwendet werden die Existenz, das Alter, die Größe oder die Zugriffsrechte auf eine Datei. Eben alles, was sich mit dem Kommando test realisieren lässt. Natürlich sollten Sie in einem Haupt-Script weiterhin die Steuerung übernehmen. Ein Beispiel:

# Name: mainscript
FILE=tmpfile.tmp
rm $FILE
touch $FILE
while true
do
  # Ist die Datei lesbar
  if [ -r $FILE ]
  then
     echo "Datei wird gelesen ..."
     sleep 1
     #./script_zum_Lesen
     # Freigeben zum Schreiben
     chmod 0200 $FILE;
  fi
  if [ -w $FILE ]
  then
     echo "Datei ist bereit zum Schreiben ..."
     sleep 1
     #./script_zum_Shreiben
     # Freigeben zum Lesen
     chmod 0400 $FILE
  fi
  sleep 1
done

Hier wird in einer Endlosschleife immer überprüft, ob eine Datei lesbar oder schreibbar ist und dann eben entsprechende Aktionen ausgeführt. Selbiges könnten Sie übrigens auch ohne eine extra Datei mit einer globalen Variablen erledigen. Sie überprüfen in einer Endlosschleife ständig den Wert der globalen Variablen und führen entsprechende Aktionen aus. Nach der Ausführung einer Aktion verändern Sie die globale Variable so, dass eine weitere Aktion ausgeführt werden kann.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

 << zurück
  
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Shell-Programmierung
Shell-Programmierung
bestellen
 Buchtipps
Zum Rheinwerk-Shop: Shell-Programmierung






 Shell-Programmierung


Zum Rheinwerk-Shop: Linux-Server






 Linux-Server


Zum Rheinwerk-Shop: Das Komplettpaket LPIC-1 & LPIC-2






 Das Komplettpaket
 LPIC-1 & LPIC-2


Zum Rheinwerk-Shop: Linux-Hochverfügbarkeit






 Linux-
 Hochverfügbarkeit


Zum Rheinwerk-Shop: Linux Handbuch






 Linux Handbuch


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2005
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern