1.8 Shellscripts schreiben und ausführen
Sie finden hier eine Anleitung, wie Sie gewöhnlich vorgehen können, um eigene Shellscripts zu schreiben und auszuführen.
1.8.1 Der Editor
Zu Beginn steht man immer vor der Auswahl seines Werkzeugs. In der Shell-Programmierung reicht hierfür der einfachste Editor aus. Welchen Editor Sie verwenden, hängt häufig vom Anwendungsfall ab. Obgleich ich hier ein Buch zur Shellscript-Programmierung schreibe, gestehe ich, kein großer Fan der Editoren »vi« und »emacs« zu sein. Ich verwende, wenn irgend möglich, einen Editor einer grafischen Oberfläche wie »Kate« unter KDE, »Gedit« unter dem GNOME-Desktop oder »xemacs« auf einer X11-Oberfläche.
Trotzdem habe ich die Mühe nicht gescheut, den gewöhnungsbedürftigen Umgang mit den quasi überall vorhandenen Editoren wie »vi«, »emacs«, »joe« oder »pico« zu erlernen. Der Grund ist ganz einfach: Als Systemadministrator oder Webmaster (mit Zugang über SSH) haben Sie nicht überall die Möglichkeit, auf eine grafische Oberfläche zurückzugreifen. Häufig sitzen Sie dann vor einem Rechner mit einer nackten Shell. Wenn Sie dann nicht wenigstens den grundlegenden Umgang mit (mindestens) »vi« beherrschen, sehen Sie ziemlich alt aus. Zwar besteht meistens noch die Möglichkeit eines Fernzugriffs zum Kopieren mit dem Kommando scp, aber macht man hier bspw. einen Tippfehler, ist dieser Vorgang auf Dauer eher ineffizient. Letztendlich ist das Ihre Entscheidung.
1.8.2 Der Name des Shellscripts
Den Namen des Shellscripts, unter dem Sie dieses mit dem Editor Ihrer Wahl abspeichern, können Sie fast willkürlich wählen. Sie müssen lediglich folgende Punkte beachten:
|
Es darf kein Name verwendet werden, von dem es ein Kommando mit demselben Namen gibt (das geht, aber man sollte es nicht machen). Dies können Sie relativ einfach testen, indem Sie etwa das Kommando which mit dem Namen Ihres Scripts verwenden (bspw. which scriptname). which liefert, falls es ein Kommando mit dem Namen gibt, den Pfad zum entsprechenden Kommando zurück. Gibt which nichts zurück, scheint ein solches Kommando nicht auf dem System zu existieren. Ähnliches kann auch mit type oder man vorgenommen werden. |
|
Sie sollten nur die Zeichen A bis Z, a bis z, 0 bis 9 und _ verwenden. Auf jeden Fall sollten Sonderzeichen vermieden werden. |
Tipp Auch wenn Sie Ihr Kommando (fast) nennen können wie Sie wollen, sollten Sie auf jeden Fall versuchen, einen Namen zu wählen, der einen Sinn ergibt.
|
1.8.3 Ausführen
Das folgende Listing stellt Ihr erstes Shellscript in diesem Buch dar. Es ist ein einfaches Script, welches das aktuelle Datum anzeigt, als »wer« Sie sich eingeloggt haben, wer sich noch alles zurzeit auf dem System befindet und welchen Rechnernamen (Host) Sie verwenden. Im Augenblick ist es allerdings noch nicht so wichtig für Sie zu wissen, was das Shellscript genau macht (auch wenn es eigentlich nicht kompliziert ist). Hier geht es nur um die Ausführung eines Shellscripts. Tippen Sie das Beispiel in den Editor Ihrer Wahl und speichern Sie es ab (im Beispiel wurde der Name userinfo verwendet).
# Script-Name: userinfo
# zeigt das aktuelle Datum an
date
# gibt die Textfolge "Ich bin ..." aus
echo "Ich bin ..."
# Wer bin ich ... ?
whoami
echo "Alle User, die eingeloggt sind ..."
# zeigt alle aktiven User an
who
echo "Name des Host-Systems ..."
# gibt den Hostnamen (Rechnernamen) aus
hostname
Hinweis Natürlich müssen Sie hier nicht alles abtippen. Sie finden alle Shellscripts auch auf der Buch-CD. Dennoch ist es aus Übungsgründen zu empfehlen, die meisten Shellscripts selbst zu schreiben, um ein Gefühl dafür zu bekommen.
|
Bevor Sie Ihr erstes Script ausführen können, müssen Sie gewöhnlich noch das Ausführrecht setzen. In Ihrem Fall ist dies das Ausführrecht (x) für den User (Dateieigentümer):
you@host > ls -l userinfo
-rw-r--r-- 1 you users 286 2005–01–21 02:19 userinfo
you@host > chmod u+x userinfo
you@host > ls -l userinfo
-rwxr--r-- 1 you users 286 2005–01–21 02:19 userinfo
Hinweis Wenn Ihnen die oktale Schreibweise etwas geläufiger ist, können Sie selbstverständlich auch chmod damit beauftragen, das Ausführrecht zu setzen:
chmod 0744 userinfo
|
Jetzt können Sie das Script beim Namen aufrufen. Allerdings werden Sie gewöhnlich den absoluten Pfadnamen verwenden müssen, es sei denn, Sie fügen das entsprechende Verzeichnis (wo sich das Script befindet) zur Umgebungsvariablen PATH hinzu (aber dazu später mehr). Somit lautet ein möglicher Aufruf des Scripts wie folgt:
you@host > ./userinfo
Fr Jan 21 02:35:06 CET 2005
Ich bin ...
you
Alle User, die eingeloggt sind ...
you :0 Jan 20 23:06 (console)
ingo :0 Jan 20 12:02 (console)
john pts/0 Jan 1 16:15 (pd9e9bdc0.dip.t-dialin.net)
john pts/2 Jan 1 16:22 (pd9e9bdc0.dip.t-dialin.net)
Name des Host-Systems ...
goliath.speedpartner.de
Hier wird mit ./ das aktuelle Verzeichnis verwendet. Starten Sie das Script aus einem anderen Verzeichnis, müssen Sie eben den absoluten Pfadnamen angeben:
you@host:~/irgend/wo > /home/tot/beispielscripte/Kap1/userinfo
Damit Sie verstehen, wie ein Shellscript ausgeführt wird, muss ich Ihnen leider noch ein Shellscript aufdrücken, bevor Sie mit den eigentlichen Grundlagen der Shell beginnen können. Es ist nämlich von enormer Bedeutung, dass Sie verstehen, dass nicht die aktuelle Shell das Script ausführt. Zum besseren Verständnis:
you@host > ps -f
UID PID PPID C STIME TTY TIME CMD
you 3672 3658 0 Jan20 pts/38 00:00:00 /bin/bash
you 7742 3672 0 03:03 pts/38 00:00:00 ps -f
Sie geben hier mit ps –f die aktuelle Prozessliste (hier unter Linux mit der Bash) der Shell auf den Bildschirm aus. Hier lautet die Prozessnummer (PID) der aktuellen Shell 3672. Die Nummer des Elternprozesses (PPID), der diese Shell gestartet hat, lautet hierbei 3658. Im Beispiel war dies der Dämon »kdeinit«, was hier allerdings jetzt nicht von Bedeutung ist. Den Prozess ps –f haben Sie ja soeben selbst gestartet und anhand der PPID lässt sich auch hier ermitteln, von welcher Shell dieser Prozess gestartet wurde (hier 3672, also der aktuellen Bash).
Um Ihnen jetzt zu demonstrieren, wie ein Shellscript ausgeführt wird, führen Sie bitte folgendes Script aus:
# Script-Name: finduser
# gibt alle Dateien des Users you auf dem Bildschirm aus
find / -user you -print 2>/dev/null
Ich habe hier bewusst einen Befehl verwendet, der ein wenig länger beschäftigt sein sollte. Mit dem Kommando find und den entsprechenden Angaben werden alle Dateien des Users »you« unterhalb des Wurzelverzeichnisses / auf dem Bildschirm ausgegeben. Fehlerausgaben (Kanal 2) wie bspw. »keine Berechtigung« werden nach /dev/null umgeleitet und somit nicht auf dem Bildschirm ausgegeben. Auf das Thema Umleitung wird noch gezielt eingegangen. Damit uns im Beispiel hier nicht die Standardausgabe (Kanal 1) auf dem Bildschirm stört, leiten wir diese auch beim Start des Scripts nach /dev/null (1>/dev/null) um. Und damit uns die Shell für weitere Eingaben zur Verfügung steht, stellen wir die Ausführung des Scripts in den Hintergrund (&). Somit können Sie in aller Ruhe die Prozessliste betrachten, während Sie das Script ausführen.
you@host > chmod u+x finduser
you@host > ./finduser 1>/dev/null &
[1] 8138
you@host > ps -f
UID PID PPID C STIME TTY TIME CMD
you 3672 3658 0 Jan20 pts/38 00:00:00 /bin/bash
you 8138 3672 0 03:26 pts/38 00:00:00 /bin/bash
you 8139 8138 10 03:26 pts/38 00:00:00 find / -user tot -print
you 8140 3672 0 03:26 pts/38 00:00:00 ps -f
you@host > kill $!
[1]+ Beendet ./finduser >/dev/null
Damit das Script nicht im Hintergrund unnötig Ressourcen verbraucht, wurde es mit kill $! beendet. Die Zeichenfolge »$!« ist eine Shell-Variable einer Prozessnummer vom zuletzt gestarteten Hintergrundprozess (auch hierauf wird noch eingegangen). Interessant ist für diesen Abschnitt nur die Ausgabe von ps –f:
UID PID PPID C STIME TTY TIME CMD
tot 3672 3658 0 Jan20 pts/38 00:00:00 /bin/bash
tot 8138 3672 0 03:26 pts/38 00:00:00 /bin/bash
tot 8139 8138 10 03:26 pts/38 00:00:00 find / -user tot -print
tot 8140 3672 0 03:26 pts/38 00:00:00 ps -f
Sie können hier anhand der PPID erkennen, dass von der aktuellen Shell (PID:3672) eine weitere Shell (8138) gestartet wurde. Bei dieser neuen Shell spricht man von einer Subshell. Erst diese Subshell führt anschließend das Script aus, wie unschwer anhand der PPID von find zu erkennen ist. Der Befehl ps –f hingegen wurde wiederum von der aktuellen Shell ausgeführt.
Derselbe Vorgang ist natürlich auch bei der Bourne-Shell (sh) und der Korn-Shell (ksh) möglich und nicht nur, wie hier gezeigt, unter der bash. Jede Shell ruft für das Ausführen eines Scripts immer eine Subshell auf. Die bash eine bash und die sh eine sh. Nur bei der Korn-Shell kann es sein, dass anstatt einer weiteren ksh eine sh aufgerufen wird! Wie Sie dies ermitteln können, haben Sie ja eben erfahren.
1.8.4 Hintergrundprozess starten
Wie Sie beim Ausführen des Beispiels eben entnehmen konnten, können Sie durch das Anhängen eines Ampersand-Zeichens (&) den Prozess im Hintergrund ausführen. Dies wird gerade bei Befehlen verwendet, die etwas länger im Einsatz sind. Würden Sie im Beispiel von finduser den Prozess im Vordergrund (also normal) ausführen, müssten Sie auf das Ende des Prozesses warten, bis Ihnen der Eingabeprompt der aktuell ausführenden Shell wieder zur Verfügung steht. Dadurch, dass der Prozess in den Hintergrund gestellt wird, können Sie weitere Prozesse quasi parallel starten.
1.8.5 Ausführende Shell festlegen
Im Beispiel konnten Sie sehen, dass ich das Script in einer Bash als (Sub-)Shell ausgeführt habe. Was aber, wenn ich das Script gar nicht in der Bash ausführen will? Schreiben Sie bspw. ein Shellscript in einer bestimmten Shell-Syntax, werden Sie wohl auch wollen, dass Ihr Script eben in der entsprechenden (Sub-)Shell ausgeführt wird. Hierbei können Sie entweder die (Sub-)Shell direkt mit dem Shellscript als Argument aufrufen oder eben die auszuführende (Sub-)Shell im Script selbst festlegen.
Aufruf als Argument der Shell
Der Aufruf eines Shellscripts als Argument der Shell ist recht einfach zu bewerkstelligen:
you@host > sh finduser
Hier wird zum Ausführen des Shellscripts die Bourne-Shell (sh) als Subshell verwendet. Wollen Sie hingegen das Script mit einer Korn-Shell als Subshell aufrufen, rufen Sie das Script wie folgt auf:
you@host > ksh finduser
Ebenso können Sie auch andere Shells wie bspw. ash oder zsh verwenden. Natürlich können Sie auch testweise eine C-Shell (bspw. tcsh) aufrufen – um festzustellen, dass hier schon erste Unstimmigkeiten auftreten.
Ausführende Shell im Script festlegen (She-Bang-Zeile)
Letztendlich besteht der gewöhnliche Weg darin, die ausführende Shell im Script selbst festzulegen. Dabei muss sich in der ersten Zeile des Shellscripts die Zeichenfolge #! gefolgt von der absoluten Pfadangabe der entsprechenden Shell befinden (wird auch als She-Bang-Zeile bezeichnet). Die absolute Pfadangabe können Sie einfach mittels which ermitteln. Gewöhnlich befinden sich alle Shell-Varianten im Verzeichnis /bin oder in /usr/bin (bzw. /usr/local/bin ist auch ein Kandidat).
Wollen Sie bspw. das Shellscript finduser von einer Korn-(Sub-)Shell ausführen lassen, müssen Sie in der ersten Zeile Folgendes eintragen:
#!/bin/ksh
oder
#!/usr/bin/ksh
Somit sieht das komplette Script für die Korn-Shell so aus (davon ausgehend, dass sich die Korn-Shell in /bin befindet):
#!/bin/ksh
# Shellscript: finduser
# gibt alle Dateien des Users tot auf dem Bildschirm aus
find / -user tot -print 2>/dev/null
Für die Bash verwenden Sie:
#!/bin/bash
oder
#!/usr/bin/bash
Und für die Bourne-Shell:
#!/bin/sh
oder
#!/usr/bin/sh
Ähnlich wird diese erste Zeile übrigens auch bei Perl und anderen Skriptsprachen verwendet. Das dies funktioniert, ist nichts Magisches, sondern ein typischer Linux-UNIX-Vorgang. Beim Start eines neuen Programms (besser ist wohl Prozess) verwenden alle Shell-Varianten den Linux-UNIX-Systemaufruf exec. Wenn Sie aus der Login-Shell eine weitere Prozedur starten, wird ja zunächst eine weitere Subshell gestartet (wie bereits erwähnt). Durch den Systemaufruf exec wird der neue Prozess durch ein angegebenes Programm überlagert – egal ob dieses Programm jetzt in Form einer ausführbaren Datei (wie diese etwa in C erstellt werden) oder als Shellscript vorhanden ist. Im Fall eines Shellscripts startet exec standardmäßig eine Shell vom Typ Ihrer aufrufenden Shell und beauftragt diese Shell, alle Befehle und Kommandos der angegebenen Datei auszuführen. Enthält das Shellscript allerdings in der ersten Zeile eine Angabe wie
#! Interpreter [Argument(e)]
verwendet exec den vom Script angegebenen Interpreter zum Ausführen des Shellscripts. Als Interpreter können alle Ihnen bekannten Shell-Varianten (sofern auf dem System vorhanden) verwendet werden (wie bereits erwähnt, nicht nur eine Shell!).
An der Zeichenfolge #! in der ersten Zeile erkennt exec die Interpreterzeile und verwendet die dahinter stehenden Zeichen als Namen des Programms, das als Interpreter verwendet werden soll. Der Name Ihres Shellscripts wird beim Aufruf des Interpreters automatisch übergeben. Dieser exec-Mechanismus wird von jeder Shell zum Aufrufen eines Programms oder Kommandos verwendet. Somit können Sie sichergehen, dass der Ablauf Ihres Scripts in der richtigen Umgebung ausgeführt wird, auch wenn Sie es gewohnt sind, in einer anderen Shell zu arbeiten.
Hinweis Es sollte Ihnen klar sein, dass hinter dem Interpreternamen kein weiterer Kommentar folgen darf, weil dieser sonst als Argument verwendet würde.
|
Shellscript ohne Subshell ausführen
Es ist auch möglich, ein Shellscript ohne das vorherige Starten einer Subshell auszuführen, um es direkt von der aktuellen Shell ausführen zu lassen. Hierzu muss dem Shellscript beim Starten lediglich ein Punkt plus Leerzeichen vorangestellt werden. Dieser Vorgang wird bspw. verwendet, wenn Sie im Script Veränderungen an den (Umgebungs-)Variablen wollen. Würden Sie Ihr Script hierbei in der Subshell ausführen, so würden sich alle Veränderungen nur auf alle weiteren Aktionen der Subshell beziehen. Wenn sich die Subshell beendet, sind auch alle Änderungen an (Umgebungs-)Variablen weg.
Hinweis Vielleicht haben Sie schon mal gehört, dass man dem Inhalt von Umgebungsvariablen nicht unbedingt trauen sollte – denn jeder kann diese verändern. In diesem Fall ist es noch schlimmer, denn zum Ausführen eines Shellscripts mit einem Punkt davor benötigt der Benutzer nicht einmal Ausführrechte. Hierbei begnügt sich die Shell schon mit dem Leserecht, um munter mitzumachen.
|
Ein Beispiel, wie Sie ein Shellscript ohne Subshell ausführen können:
you@host > . ./script_zum_ausfuehren
oder mit absoluten Pfadnamen:
you@host > . /home/tot/beispielscripte/Kap1/script_zum_ausfuehren
Hinweis Die Bash kennt als Alternative zum Punkt das interne Kommando source.
|
1.8.6 Kommentare
In den Scripts zuvor wurden Kommentare bereits reichlich verwendet, und Sie sollten dies in Ihren Scripts auch regelmäßig tun. Einen Kommentar können Sie durch ein vor dem Text stehendes Hash-Zeichen (#) erkennen. Hier ein Beispiel, wie Sie Ihre Scripts kommentieren können:
#!/bin/sh
# Script-Name: HalloWelt
# Version : 0.1
# Autor : J.Wolf
# Datum : 20.05.2005
# Lizenz : ...
# ... gibt "Hallo Welt" aus
echo "Hallo Welt"
echo "Ihre Shell:"
echo $SHELL # ... gibt die aktuelle Shell aus
Zugegeben, für ein solch kleines Beispiel sind die Kommentare ein wenig übertrieben. Sie sehen hier, wie Sie auch Kommentare hinter einen Befehl setzen können. Alles, was hinter einem Hash-Zeichen steht, wird von der Shell ignoriert. Natürlich mit Ausnahme der ersten Zeile, wenn sich dort die Zeichenfolge »#!« befindet.
Kommentieren sollten Sie zumindest den Anfang des Scripts mit einigen Angaben zum Namen und eventuell dem Zweck, sofern dieser nicht gleich klar sein sollte. Wenn Sie wollen, können Sie selbstverständlich auch Ihren Namen, das Datum und die Versionsnummer angeben. Auch auf Besonderheiten bezüglich einer Lizenz sollten Sie hier hinweisen. Komplexe Stellen sollten auf jeden Fall ausreichend kommentiert werden. Dies hilft Ihnen, den Code nach längerer Abwesenheit schneller wieder zu verstehen. Sofern Sie die Scripts der Öffentlichkeit zugänglich machen wollen, wird man es Ihnen danken, wenn Sie Ihren »Hack« ausreichend kommentiert haben.
1.8.7 Stil
Jeder Programmierer entwickelt mit der Zeit seinen eigenen Programmierstil, dennoch gibt es einiges, was Sie vielleicht beachten sollten. Zwar ist es möglich, durch ein Semikolon getrennt mehrere Befehle in einer Zeile zu schreiben (wie dies ja in der Shell selbst auch möglich ist), doch sollten Sie dies, wenn möglich, der Übersichtlichkeit zuliebe vermeiden.
Und sollte eine Zeile doch mal ein wenig zu lang werden, dann können Sie immer noch das Backslash-Zeichen (\) setzen. Ein Shellscript arbeitet ja Zeile für Zeile ab. Als Zeilentrenner wird gewöhnlich das Newline-Zeichen (ein für den Editor nicht sichtbares Zeichen mit der ASCII-Code-Nummer 10) verwendet. Durch das Voranstellen eines Backslash-Zeichens wird das Newline-Zeichen außer Kraft gesetzt.
#!/bin/sh
# Script-Name: backslash
# ... bei überlangen Befehlen kann man ein Backslash setzen
echo "Hier ein solches Beispiel, wie Sie\
ueberlange Zeilen bzw. Ketten von Befehlen\
auf mehreren Zeilen ausführen können"
Bei etwas überlangen Ketten von Kommandos verhilft das Setzen eines Backslashs auch ein wenig, die Übersichtlichkeit zu verbessern:
ls -l /home/tot/docs/listings/beispiele/kapitel1/final/*.sh | \
sort -r | less
Wenn Sie etwas später auf Schleifen und Verzweigungen treffen, sollten Sie gerade hier mal eine Einrückung mehr als nötig vornehmen. Einmal mehr auf die (˙_)-Taste zu drücken, hat noch keinem geschadet.
1.8.8 Ein Shellscript beenden
Ein Shellscript beendet sich entweder nach Ablauf der letzten Zeile selbst oder Sie verwenden den Befehl exit, womit die Ausführung des Scripts sofort beendet wird. Die Syntax des Kommandos sieht wie folgt aus:
exit [n]
Der Parameter n ist optional. Für diesen Wert können Sie eine ganze Zahl von 0 bis 255 verwenden. Verwenden Sie exit ohne jeden Wert, wird der exit-Status des Befehls genutzt, der vor exit ausgeführt wurde. Mit den Werten 0 bis 255 wird angegeben, ob ein Kommando oder Script ordnungsgemäß ausgeführt wurde. Der Wert 0 steht dafür, dass alles ordnungsgemäß abgewickelt wurde. Jeder andere Wert signalisiert eine Fehlernummer.
Sie können damit auch testen, ob ein Kommando, das Sie im Script ausgeführt haben, erfolgreich ausgeführt wurde und je nach Situation das Script an einer anderen Stelle fortsetzen lassen. Hierfür fehlt Ihnen aber noch die Kenntnis der Verzweigung. Die Zahl des exit-Status kann jederzeit mit der Shell-Variablen $? abgefragt werden. Hierzu ein kurzes Beispiel:
#!/bin/sh
# Script-Name: ende
echo "Tick ..."
# ... Shellscript wird vorzeitig beendet
exit 5
# "Tack ..." wird nicht mehr ausgeführt
echo "Tack ...
Das Beispiel bei der Ausführung:
you@host > chmod u+x ende
you@host > ./ende
Tick ...
you@host > echo $?
5
you@host > ls -l /root
/bin/ls: /root: Keine Berechtigung
you@host > echo $?
1
you@host > ls -l *.txt
/bin/ls: *.txt: Datei oder Verzeichnis nicht gefunden
you@host > echo $?
1
you@host > ls -l *.c
-rw-r--r-- 1 tot users 49 2005–01–22 01:59 hallo.c
you@host > echo $?
0
Im Beispiel wurden auch andere Kommandos ausgeführt. Je nach Erfolg war hierbei der Wert der Variablen $? 1 (bei einem Fehler) oder 0 (wenn alles in Ordnung ging) – abgesehen von unserem Beispiel, wo bewusst der Wert 5 zurückgegeben wurde.
Hinweis Beachten Sie bitte, wenn Sie den Befehl exit direkt im Terminal ausführen, wird dadurch auch die aktuelle Login-Shell beendet.
|
1.8.9 Testen und Debuggen von Shellscripts
Debuggen und Fehlersuche ist auch in der Shellscript-Programmierung von großer Bedeutung, sodass diesem Thema ein extra Abschnitt gewidmet wird. Trotzdem werden Sie auch bei Ihren ersten Scripts unweigerlich den einen oder anderen (Tipp-)Fehler einbauen (es sei denn, Sie verwenden sämtliche Listings von der Buch-CD).
Am häufigsten wird dabei in der Praxis die Option –x verwendet. Damit wird jede Zeile vor ihrer Ausführung auf dem Bildschirm ausgegeben. Meistens wird diese Zeile mit einem führenden Plus angezeigt (abhängig davon, was in der Variablen PS4 enthalten ist). Als Beispiel diene folgendes Shellscript:
#!/bin/sh
# Script-Name: prozdat
# Listet Prozessinformationen auf
echo "Anzahl laufender Prozesse:"
# ... wc -l zählt alle Zeilen, die ps -ef ausgeben würde
ps -ef | wc -l
echo "Prozessinformationen unserer Shell:"
# ... die Shell-Variable $$ enthält die eigene Prozessnummer
ps $$
Normal ausgeführt ergibt dieses Script folgende Ausgabe:
you@host > ./prozdat
Anzahl laufender Prozesse:
76
Prozessinformationen unserer Shell:
PID TTY STAT TIME COMMAND
10235 pts/40 S+ 0:00 /bin/sh ./prozdat
Auch hier wollen wir uns zunächst nicht zu sehr mit dem Script selbst befassen. Jetzt soll die Testhilfe mit der Option –x eingeschaltet werden:
you@host > sh -x ./prozdat
+ echo 'Anzahl laufender Prozesse:'
Anzahl laufender Prozesse:
+ ps -ef
+ wc -l
76
+ echo 'Prozessinformationen unserer Shell:'
Prozessinformationen unserer Shell:
+ ps 10405
PID TTY STAT TIME COMMAND
10405 pts/40 S+ 0:00 sh -x ./prozdat
Sie sehen, wie jede Zeile vor ihrer Ausführung durch ein voranstehendes Plus ausgegeben wird. Außerdem können Sie hierbei auch feststellen, dass die Variable $$ durch den korrekten Inhalt ersetzt wurde. Selbiges wäre übrigens auch bei der Verwendung von Sonderzeichen (Wildcards) wie * der Fall. Sie bekommen mit dem Schalter –x alles im Klartext zu sehen.
Bei längeren Scripts ist mir persönlich das Pluszeichen am Anfang nicht deutlich genug. Wenn Sie dies auch so empfinden, können Sie die Variable PS4 gegen eine andere beliebige Zeichenkette austauschen. Ich verwende hierfür sehr gern die Variable LINENO, die nach der Ausführung immer durch die entsprechende Zeilennummer ersetzt wird. Die Zeilennummer hilft mir dann bei längeren Scripts, immer gleich die entsprechende Zeile zu finden. Hier ein Beispiel, wie Sie mit PS4 effektiver Ihr Script debuggen können:
you@host > export PS4='[--- Zeile: $LINENO ---] '
you@host > sh -x ./prozdat
[--- Zeile: 6 ---] echo 'Anzahl laufender Prozesse:'
Anzahl laufender Prozesse:
[--- Zeile: 8 ---] ps -ef
[--- Zeile: 8 ---] wc -l
76
[--- Zeile: 10 ---] echo 'Prozessinformationen unserer Shell:'
Prozessinformationen unserer Shell:
[--- Zeile: 12 ---] ps 10793
PID TTY STAT TIME COMMAND
10793 pts/40 S+ 0:00 sh -x ./prozdat
1.8.10 Shellscript, das ein Shellscript erstellt und ausführt
Hand aufs Herz: Wie oft haben Sie bis hierher schon einen Fluch ausgestoßen, weil Sie bspw. vergessen haben, das Ausführrecht zu setzen, oder waren davon genervt, immer wiederkehrende Dinge zu wiederholen? Dazu lernen Sie ja eigentlich Shellscript-Programmierung, nicht wahr? Somit liegt nichts näher, als Ihnen hier eine kleine Hilfe mitzugeben. Ein Shellscript, welches ein neues Script erstellt oder ein bereits vorhandenes Script in den Editor Ihrer Wahl lädt. Natürlich soll auch noch das Ausführrecht für den User gesetzt werden und bei Bedarf wird das Script ausgeführt. Hier das simple Script:
# Ein Script zum Script erstellen ...
# Name : scripter
# Bitte entsprechend anpassen
#
# Verzeichnis, in dem sich das Script befindet
dir=$HOME
# Editor, der verwendet werden soll
editor=vi
# erstes Argument muss der Scriptname sein ...
[ -z "$1" ] && exit 1
# Editor starten und Script laden (oder erzeugen)
$editor $dir/$1
# Ausführrechte für User setzen ...
chmod u+x $dir/$1
# Script gleich ausführen? Nein? Dann auskommentieren ...
$dir/$1
Sie müssen bei diesem Script lediglich die Variablen »dir« und »editor« anpassen. Mit der Variable »dir« geben Sie das Verzeichnis an, wohin das Script geladen oder eventuell abgespeichert werden soll. Im Beispiel wurde einfach mit der Shell-Variablen HOME das Heimverzeichnis des eingeloggten Users verwendet. Als Editor verwende ich vi. Hier können Sie auch einen Editor Ihrer Wahl eintragen. Mit [ –z "$1" ] (z steht für zero, also leer) wird überprüft, ob das erste Argument der Kommandozeile ($1) vorhanden ist. Wurde hier keine Angabe gemacht, beendet sich das Script gleich wieder mit exit 1. Die weitere Ausführung spricht, glaube ich, erst einmal für sich. Aufgerufen wird das Script wie folgt:
you@host > ./scripter example
Natürlich ist es nicht meine Absicht, dem Einsteiger mit diesem Script eine Einführung in die Shellscript-Programmierung zu geben, sondern hier geht es nur darum, Ihnen eine kleine Hilfe an die Hand zu geben, um effektiver mit dem Buch arbeiten zu können.
Nachdem bis hierhin alle Formalitäten geklärt wurden, können Sie endlich damit loslegen, die eigentliche Shellscript-Programmierung zu erlernen. Zugegeben, es waren viele Formalitäten, aber dies war aus meiner Sicht unbedingt nötig.
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.
|