Betriebssysteme UNIX/Linux Übungsthema 7 - FB2

Werbung
Betriebssysteme
UNIX/Linux
Übungsthema 7
“die Shell und Shell-Skripte”
Dirk Wenzel
Dr. Jörg Gruner
SS 2006
Inhalte:
Shell und Shell-Skripte
Shell-Variable und die Systemumgebung
einfache Shell-Skripte
fortgeschrittene Shell-Skripte
Start-Up Shell-Skripte
1. Die Shell und Shell-Skripte
Eine Shell ist ein Programm, das Benutzerkommandos liest und ausführt. Zudem unterstützen
Shells die Kontrolle über Programme, die Ein- und Ausgabe-Umleitung sowie eine eigene
Kommandosprache um Shell-Skripte zu schreiben. Ein Shell-Skript ist eine einfache Textdatei, die
eine Reihe von Kommandos einer Shell-Kommando-Sprache enthält (wie eine Batch-Datei unter
Windows, z.B. autoexec.bat).
Es sind viele unterschiedliche Shells unter UNIX-Systemen verfügbar (z.B. sh, bash, csh, ksh,
tcsh, usw.), wovon jede eine eigene Kommandosprache unterstützt. Hier wollen wir die
Kommandosprache der Bourne-Shell (sh) verwenden, da sie in den meisten UNIX-Systemen zur
Verfügung steht. Sie wird auch von der bash und der ksh unterstützt.
2. Shell Variablen und die Systemumgebung
In einer Shell können, wie in den meisten Programmiersprachen, Variablen definiert werden. Eine
Variable hat einen Namen und einen Inhalt. Wurde einer Variablen ein Wert zugewiesen, so kann
er mit dem Zeichen $ ausgelesen werden.
Beispiel:
> bob='hello world'
> echo $bob
hello world
>
In der aktuellen Shell erzeugte Variabele sind lokal und somit nur in dieser Shell ansprechbar. Mit
dem Kommando set wird eine Liste aller Variablen angezeigt, die momentan in der Shell
definiert sind. Sollen Variable auch für Kommanos außerhalb der Shell verfügbar sein, kann man
sie in die Umgebung (environment) exportieren.
> export bob //unter csh wird setenv verwendet!
Die Umgebung (environment) ist eine Sammlung von Variablen, die den Kommandos bei deren
Ausführung (einschließlich der Shell) zur Verfügung stehen. UNIX Kommandos und Programme
können die Werte von Umgebungsvariablen lesen und sich dementsprechend verhalten. So wird
z.B. die Umgebungsvariable PAGER vom man Kommando (und auch noch von anderen)
ausgelesen, um festzustellen, mit welchem Kommando Multiseiten angezeigt werden.
Beispiel:
Setzen Sie die Umgebungsvariable wie folgt
> export PAGER=cat
Dirk Wenzel, Dr. Jörg Gruner
Seite 1
und starten Sie das man-Kommando (z.B. man pwd). Die Seite wird nun ohne anzuhalten über
den Monitor fliegen. Setzen Sie PAGER nun auf more und testen Sie erneut mit man pwd.
> export PAGER=more
Eine weitere oft genutzte Umgebungsvariable ist EDITOR, welche den Standardeditor definiert.
Sie können diese auf vi, emacs oder einen anderen Editor ihrer Wahl setzen. Um herauszufinden,
welche Umgebungsvariable alle von einem bestimmten Kommando verwendet werden, müssen die
man-pages zu Rate gezogen werden.
Eine weitere interessante Umgebungsvariable ist PS1, die den Promptstring (das sind die Zeichen,
die links von der Eingabemarke stehen) der Shell festlegen.
Beispiel:
> export PS1="(\h) \w> "
(lumberjack) ~>
So können z.B. für die bash folgende Zeichen verwendet werden:
\h aktueller Host
\w aktuelles Arbeitsverzeichnis
\d Datum
\t Zeit
\u aktueller Benutzer
weitere Infos finden Sie in den man-pages zur bash
Eine weitere viel genutzte Umgebungsvariable ist PATH. Sie beinhaltet eine Liste von
Pfadangaben, in denen die Shell nach ausführbaren Programmen sucht. Ist z.B. PATH gesetzt wie
folgt:
/bin:/usr/bin:/usr/local/bin:.
und Sie geben das Kommando ls ein, wird die Shell in /bin, /usr/bin usw. nachschauen, ob
es dort zu finden ist und dann ausführen. Ansonsten kommt eine Fehlermeldung. Achten Sie
darauf, dass auch das aktuelle Arbeitsverzeichnis gesetzt ist '.'. Somit können Sie erstellte
Shellskripte und Programme in deren aktuellem Verzeichnis ausführen, ohne immer "./" (also:
./myprogramm) voranstellen zu müssen!
Beachten Sie, dass PATH nichts mit Angaben von Argumenten hinter dem Kommando zu tun hat.
So wird für cat myfile.txt nur nach ./myfile gesucht und nicht nach
/bin/myfile.txt usw.
3. einfache Shell-Skripte
So sieht ein ganz einfaches Schellskript aus, welches in einem Texteditor erstellt wurde und den
Dateinamen simple hat.
#!/bin/sh
# Dies ist ein Kommentar
Dirk Wenzel, Dr. Jörg Gruner
Seite 2
echo
echo
echo
echo
echo
read
echo
"Die Anzahl der Argumente ist $#"
"Die Argumente sind $*"
"Das erste ist $1"
"Meine Prozess-ID ist $$"
"Geben Sie eine Zahl über die Tastatur ein: "
number
"Die eingegebene Nummer lautet $number"
Das Shellskript beginnt mit der Zeile "#!/bin/sh". Normalerweise bezeichnet "#" eine
Kommentarzeile, aber "#!" ist eine besondere Kombination, die UNIX mitteilt, dass die
Bourne-Shell (sh) zur Ausführung des Skripts verwendet werden soll. Die Zeichenfolge "#!"
muss ganz am Anfang des Skripts stehen, also die ersten beiden Zeichen. Die Argumente, die
dem Skript mit übergeben werden, können mit $1, $2, $3 usw. angesprochen werden. das $*
steht für alle Argumente und $# steht für die Anzahl der Argumente. Die Prozess-ID (PID) der
Shell, die das Skript gerade ausführt, wird mit $$ ausgegeben. Der Befehl read liest Zeichen
über die Tastatur ein und schreibt sie in die Variable number.
Um das Skript nun starten zu können, muss es zuerst ausführbar gemacht werden!
> ls –l simple
-rw-r—r-1
user group
245 Nov 27
> chmod +x simple
> ls –l simple
-rwxr—xr-x
1
user group
245 Nov 27
> ./simple hello world
Die Anzahl der Argumente ist 2
Die Argumente sind hello world
Das erste ist hello
Meine Prozess-ID ist 1783
Geben Sie eine Zahl über die Tastatur ein:
24
Die eingegebene Nummer lautet 24
>
simple
simple
4. fortgeschrittene Shell-Skript Programmierung
if-then-else Anweisung
Shell-Skripte unterstützen einfache Ja/Nein-Abfragen (bedingte Anweisungen).
Syntax:
if [ test ] then
kommandos-wenn-test-wahr-ist
else
kommandos-wenn-test-falsch-ist
fi
Die test Bedingung kann auf Dateieigenschaften, einfache Zeichenketten oder
numerische Vergleiche angewandt werden. Die eckige Klammer "[" steht für ein
Kommando (/bin/[), welches die Überprüfung der test-Bedingung unterstützt. Dazu
Dirk Wenzel, Dr. Jörg Gruner
Seite 3
müssen allerdings Leerzeichen zwischen den eckigen Klammern und der test-Bedingung
sein.
Liste grundlegender test-Bedingungen:
-s file
-f file
-d file
-r file
-w file
-x file
$X –eq $Y
$X –ne $Y
$X –lt $Y
$X –gt $Y
$X –le $Y
$X –ge $Y
"$A" = "$B"
"$A" != "$B"
$X ! –gt $Y
$E –a $F
$E –o $F
wahr wenn file existiert und nicht leer ist
wahr wenn file eine einfache Datei ist
wahr wenn file ein Verzeichnis ist
wahr wenn file lesbar ist
wahr wenn file beschreibbar ist
wahr wenn file ausführbar ist
wahr wenn X gleich Y ist
wahr wenn X ungleich Y ist
wahr wenn X kleiner Y ist
wahr wenn X größer Y ist
wahr wenn X kleiner gleich Y ist
wahr wenn X größer gleich Y ist
wahr wenn Ausdruck A gleich Ausdruck B ist
wahr wenn Ausdruck A ungleich Ausdruck B ist
wahr wenn Ausdruck X nicht größer Ausdruck Y ist
wahr wenn Ausdruck E und F beide gleich (AND)
wahr wenn Ausdruck E oder F beide gleich (OR)
for Schleifen
Manchmal ist es nötig, eine Liste von Dateien zu durchlaufen und auf jede Datei ein
Kommando anzuwenden. Dies kann mit einer for-Schleife geschehen:
for variable in list
do
kommandos
done
//beziehen sich auf $variable
Das folgende Skript sortiert alle Textdateien im aktuellen Verzeichnis:
#!/bin/sh
for f in *.txt
do
echo sorting file $f
cat $f | sort > $f.sorted
echo sorted file has been output to $f.sorted
done
while Schleifen
Eine weitere Schleifenart ist die while-Schleife:
while [ test ]
do
kommandos
done
Dirk Wenzel, Dr. Jörg Gruner
Seite 4
Das folgende Skript wartet, bis eine nicht leere Datei input.txt erzeugt wurde:
#!/bin/sh
while [ ! –s input.txt ]
do
echo waiting ...
sleep 5
done
echo input.txt is ready
Sie können ein Shell-Skript mit der exit-Anweisung an einer beliebigen Stelle abbrechen.
Beispiel:
#!/bin/sh
while [ ! –s input.txt ]
do
if [ -s input.txt ]
echo input.txt is ready
exit
fi
echo waiting ...
sleep 5
done
case Anweisung
Die case-Anweisung ist eine weitere Möglichkeit, Bedingungen abzufragen. Der
auszuwertende Ausdruck wird mit mehreren Alternativen verglichen.
case variable in
pattern1)
kommandos (wird ausgeführt, wenn variable auf
pattern1 zutrifft)
;;
pattern2)
kommandos (wird ausgeführt, wenn variable auf
pattern2 zutrifft)
;;
usw.
esac
Das folgende Skript verwendet die case-Anweisung, um eine Auswahl von Dateien, die
nicht ausführbar sind, zutreffen und nach ihrer Dateiendung (extension) zu charakterisieren.
Beachten Sie, wie der OR-Operator "|" eingesetzt wird, um nach multiplen Ausdrücken zu
suchen, wie "*" eingesetzt wird, um alle Treffer auszuwerten und die Wirkung von
sogenannten forward single quotes "`".
#!/bin/sh
for f in $*
do
if [ -f $f –a ! –x $f ]
then
Dirk Wenzel, Dr. Jörg Gruner
Seite 5
done
fi
case $f in
core)
echo "$f: a core dump file"
;;
*.c)
echo "$f: a C programm"
;;
*.cpp|*.cc|*.cxx)
echo "$f: a C++ programm"
;;
*.txt)
echo "$f: a text file"
;;
*.pl)
echo "$f: a PEARL script"
;;
*.html|*.htm)
echo "$f: a web document"
;;
*)
echo "$f: appears to be "`file –b $f`
;;
esac
Umleitung der Ausgabe von Kommandos in eine Variable
Jedes UNIX Kommando kann, anstelle über die Kommandozeile, ebenso von einem ShellSkript ausgeführt werden. Die Ausgabe eines Kommandos kann darin mit Hilfe der forward
single quotes (``) in eine Variable geschrieben und weiterverwendet werden:
#!/bin/sh
lines=`wc –l $1`
echo "Die Datei $1 hat $lines Zeilen"
Dieses Skript gibt die Anzahl der Zeilen in der Datei aus, die den ersten Parameter
enthalten.
arithmetische Operationen
Die Bourne-Shell hat keine Implementierungen um einfache mathematische Ausdrücke
auszuwerten. Das UNIX-Kommando expr kann stattdessen dazu verwendet werden. Es
wird oft in Shell-Skripten mit forward-single-quotes verwendet, um die Werte von
Variablen zu aktualisieren.
Beispiel:
lines = `expr $lines + 1`
addiert 1 zu der Variablen lines dazu. expr unterstützt die Operatoren +, -, *, /,
%(remainder), <, <=, =, !=, >=, >, |(OR) und &(AND).
5. Start-Up Shell-Skripte
Dirk Wenzel, Dr. Jörg Gruner
Seite 6
Beim ersten Einloggen in eine Shell arbeitet diese ein systemweites start-up-Skript ab.
Gewöhnlich ist dies /etc/profile bei sh, bash und ksh und /etc/.login bei der csh.
Dann wird in Ihrem Homeverzeichnis nach eigenen start-up-Skripten weitergesucht, also
.profile bei sh, bash und ksh und .cshrc bei der csh und tcsh. Ihr eigenes start-upSkript ist somit ein guter Platz, um eigene Umgebungsvariable abzusetzen wie z.B. PATH,
EDITOR oder auch selbst definierte.
So kann z.B. das Verzeichnis ~/bin zur Umgebungsvariable PATH in der bash wie folgt in
.profile hinzugefügt werden:
> source ./profile
Um nun die Änderungen für die aktuelle Shell zu aktuallisieren, geben Sie
> . ./profile
oder
export PATH=$PATH:~/bin
ein.
Das Kommando source ist in der Shell eingebaut. Es stellt sicher, dass Änderungen in der
Umgebung, also dem environment, die in .profile vorgenommen wurden, sich auch in der
aktuellen Shell auswirken.
Dirk Wenzel, Dr. Jörg Gruner
Seite 7
Übungsblatt 7:
“die Shell und Shell-Skripte”
1. Erstellen Sie mit ihrem Lieblings-Editor (das ist doch jetzt bestimmt der vi, oder ☺) das
Shell-Skript simple aus Kap.3. Starten Sie es anschließend und schauen Sie, wie sich die
Inhalte auf die Ausgabe auswirken.
2. Erweitern Sie das Skript so, dass Sie in die Variable ratemich eine geheime Zahl
zwischen 1 und 100 schreiben. Lassen Sie ihren Nachbarn dann die richtige Zahl erraten.
Das Skript soll Hinweise geben wie z.B. "Sorry, Ihre Schätzung ist zu niedrig!", "Sorry,
Ihre Schätzung ist zu hoch!" oder "Vollltreffer!".
3. Schreiben Sie ein Shell-Skript, dass alle .txt Dateien in .text umbenennt. Das
Kommando basename könnte hier hilfreich sein. Erzeugen Sie in einem Verzeichnis ein
paar Dateien .txt (ohne Inhalt) und testen Sie das Skript.
4. Schreiben Sie ein Shell-Skript pidof, welches einen Namen als Parameter übernimmt und
den PID bzw. die PIDs von Prozessen mit diesem Namen ausgibt.
5. Shell-Skripte können auch Funktionen enthalten. Funktionen werden wie folgt deklariert:
funcname() {
Anweisungen
}
und aufgerufen mit funcname param1 param2 ... . Die Parameter sind innerhalb der
Funktion über $1, $2 usw. ansprechbar. Fügen Sie nun die Funktion usage() dem
pidof-Skript hinzu, welches dem Anwender Informationen zum Umgang mit dem Skript
ausgibt. Rufen Sie usage() auf, wenn eine falsche Anzahl an Parametern beim Aufruf
von pidof übergeben wird.
6. Modifizieren Sie ihr .bashrc start-up-Skript so, dass die PATH-Variable das aktuelle
Verzeichnis "." enthält und die Umgebungsvariable EDITOR auf vi, emacs oder einen
Editor Ihrer Wahl gesetzt ist. Starten Sie das modifizierte Skript mit source .bashrc
und prüfen Sie, ob die Änderungen in der aktuellen Shell funktioniert haben. Verwenden
Sie dazu das Kommando set bzw. env.
Dirk Wenzel, Dr. Jörg Gruner
Seite 1
Herunterladen