- Erste Ausgabe
- Benutzereingaben
- Ein wenig rechnen
- Argumente
- If-Abfragen
- test testen
- Schleifen
- Erstes kleines Programm
- 6 aus 49
- Lock-Screen
- Idealgewicht
Shell-Scripts (Kommandoprozeduren) können mit Batch-Dateien unter MS-Dos verglichen werden, sind jedoch wesentlich leistungsfähiger.
Ein Shell-Script ist eine Textdatei, in der Kommandos gespeichert sind. Es stellt selbst ein Kommando dar, da es wie ein Systemkommando, auch mit Parametern, aufgerufen werden kann. Shell-Scripts dienen der Arbeitserleichterung und (nach ausreichenden Tests) der Erhöhung der Zuverlässigkeit, da sie gestatten, häufig gebrauchte Sequenzen von Kommandos zusammenzufassen.
Ein Anwendungsbeispiel wäre das nächtliche Kopieren von wichtigen Daten auf einen anderen Rechner im Netzwerk, oder das bearbeiten (z.B. umbenennen oder Rechte setzen) vieler Datein auf einen Schlag.
Es gibt unzählige weitere Anwendungsmöglichkeiten.
Voraussetzungen
Um dieses Tutorial durchführen zu können, benötigen wir Zugang zu einem Unix-Rechner (Linux, OS X).
Stellt dies kein Problem dar sollten wir und mit der Navigation in der Verzeichnis-Struktur des Systems schon einmal befasst haben. Sprich: das wechseln in ein anderes Verzeichnis, wissen, was das Home-Verzeichnis ist und wie wir da wieder hin kommen.
Das ist aber auch schon alles, was wir an Voraussetzungen benötigen.
Was bringt mir dieses Tut?
Am Ende dieses Tutorials haben wir einen kleinen Überblick über Standard-Kontrollstrukturen und Grund-Befehle, die in fast jedem Shell-Script vorkommen.
Wir versuchen einen Wissensstand zu erlangen, so dass wir in Zukunft eine Problemstellung erkennen und wissen, wie wir an die Lösung heran gehen.
Dazu gehört auch das Wissen, es gibt unzählige weitere Möglichkeiten / Tools (einige werden wir kennen lernen), die wir zur Lösung unseres Problems verwenden können.
Kurz: wir eignen uns hier die Basics an...
Fangen wir langsam an...
-- Erste Ausgabe --
Was wollen wir machen?- wir wollen, weil das einfach immer so ist, einfach mal mit der "Hallo Welt"-Ausgabe beginnen :o)
Wir öffnen die Konsole (Terminal) und legen am besten erst mal einen Ordner an, in dem wir alle unsere Scripte ablegen. Nennen wir den Ordner beispielsweise "shellscripte":
(alles was ab jetzt in den Code-Bereichen steht, spielt sich im Terminal / in der Konsole ab!)
Code :
1 | mkdir shellscripte |
Code :
1 | cd shellscripte |
Zuerst aber legen wir die Datei mit dem Namen "01_ausgabe" an
Code :
1 | touch 01_ausgabe |
Jetzt öffnen wir mit dem vi-Editor die ebend angelegte Datei
Code :
1 | vi 01_ausgabe |
Code :
1 | echo "Hallo Welt" |
Jetzt wollen wir das Script speichern und den vi verlassen. Dazu drücken wir bei gedrückter Shift-Taste zwei mal die Z-Taste drücken.
(wesentlich bekannter ist die Variante an dieser Stelle :wq einzugeben und mit Enter zu bestätigen. Jeder so wie er es mag...
)Jetzt befinden wir uns wieder direkt in der Konsole und können unser Script testen
Code :
1 | sh 01_ausgabe |
-- Benutzereingaben --
Was wollen wir machen?- da man irgendwann immer an dem Punkt ankommt, wo eine Eingabe unbedingt erforderlich ist, werden wir uns jetzt mal darum kümmern
Legen wir das script an und öffnen es zum Bearbeiten mit dem vi.
Code :
1 2 3 | touch 02_eingaben
vi 02_eingaben |
Code :
1 2 3 4 5 6 7 | clear
echo -n "Bitte geben Sie Ihren Namen ein: "
read name
echo ""
echo "Mein Name ist $name." |
Mit dem Schlüsselwort "clear" wird die Konsole 'aufgeräumt', sprich: der Inhalt gelöscht. Werden wir gleich sehen, wenn wir das Script ausführen.
Wir wollen uns gleich von Anfang an angewöhnen, die Übersicht zu behalten. Darum auch nach "clear" eine Leerzeile.
Was "echo" und bringt, wissen wir ja bereits. Neu ist hier nur das Argument '-n'. Mit diesem Argument geben wir an, dass der Cursor am Ende der Ausgabe stehen bleiben soll, so dass wir unseren Namen in der gleichen Zeile eingeben müssen.
Das Werkzeug "read" nimmt dann unseren eingegebenen Namen entgegen und speichert ihn in der Variable 'name'.
Mit dem nun folgenden "echo"-Befehl fügen wir einfach nur eine Leerzeile bei der späteren Ausgabe ein.
Nun kommen wir zur eigentlichen Ausgabe.
Gar nicht schwer! Wir nehmen die eben gefüllte Variable 'name' mit in unsere Ausgabe auf.
Uns fällt auf, dass dort plötzlich ein Doller-Zeichen vorangestellt ist. Immer wenn wir an den Wert einer Variable wollen, also den Inhalt auslesen möchten, schreiben wir ein $-Zeichen vor die Variable.
Speichern wir wieder mit gedrückter Shift-Taste und zweimaligen drücken der z-Taste und führen das Script aus.
Code :
1 | sh 02_eingaben |
Code :
1 2 3 | Bitte geben Sie Ihren Namen ein: Gerrit
Mein Name ist Gerrit. |
Dazu legen wir keine neue Datei an. Wir erweitern das Script von eben, also öffnen wir es mit vi, indem wir das zu öffnende Script direkt als Argument mit übergeben.
Code :
1 | vi 02_eingaben |
Code :
1 2 3 4 5 6 7 8 9 10 | clear
echo -n "Bitte geben Sie Ihren Namen ein: "
read name
[B]echo -n "und wie alt sind Sie? "
read alter[/B]
echo ""
echo "Mein Name ist $name [B]und ich bin $alter Jahre alt."
echo ""[/B] |
Rufen wir das Script jetzt auf,
Code :
1 | sh 02_eingaben |
Ich denke, das Prinzip ist klar :o)
-- Ein wenig rechnen --
Was wollen wir machen?- wir nehmen ein weiteres Werkzeug mit dem Namen "expr" aus der Unix-Werkzeugkiste und werden uns mal anschauen, was damit so möglich ist
(alle Funktionen können nicht erklärt werden, da das in einem Buch enden würde - für weitere informationen geben Sie in der Konsole "man expr" ein oder
)
"expr" ist ein mächtiges Rechenwerkzeug. Ein paar Beispiele in der Konsole eingetippt und mit der Enter-Taste bestätigt:
Code :
1 | expr 2 + 5 |
Code :
1 | expr 100 - 19 |
Code :
1 | expr 10 % 3 |
Code :
1 | touch 03_ein_wenig_rechnen |
Wenn wir das Script nun im vi öffnen möchten, wissen wir ja, dass wir vi gefolgt von dem Dateinamen eingeben müssen. Um uns die Arbeit erleichtern zu können, tippen wir jetzt aber nur
Code :
1 | vi 03 |
Der Dateiname wird vervollständigt und wir können unsere Eingabe mit 'Enter' bestätigen.
Code :
1 2 3 4 5 6 7 8 9 10 | clear
# Variablen mit Werten fuellen
z1=10
z2=11
erg=`expr $z1 + $z2`
echo "$z1 + $z2 ist $erg!"
echo "" |
Die Zeile, die mit dem #-Zeichen beginnt, leitet einen Kommentar ein, in den wir schreiben können, was wir möchten. Diese Zeile wird beim Ausführen ignoriert.
Wir addiren die zwei Zahlen und speichern sie in einer weiteren Variable mit dem Namen 'erg'.
Verwunderlich sind die komischen Fliegenschisse vor und nach dem expr-Befehl (der Berechnung).
Diese Zeichen bekommen wir, indem wir bei gedrückter "Shift"-Taste die "`"-Taste drücken (zu finden direkt rechts neben dem Fragezeichen.
Mit diesem Zeichen teilen wir dem Shellscript mit, dass wir ein Werkzeug aufrufen, mit dessen Ergebnis wir etwas machen wollen. In diesem Fall das Abspeichern in 'erg'.
Speichern wir das Script so und führen es aus, so werden wir folgende Ausgabe bekommen:
Code :
1 | 10 + 11 ist 21! |
Code :
1 2 3 4 5 6 7 8 | clear
# Variablen mit Werten fuellen
z1=10
z2=11
echo "$z1 + $z2 ist `[B]expr $z1 + $z2[/B]`!"
echo "" |
Wir wollen Die Zahl, die zu 10 addiert werden soll, selber eingeben.
Das sieht dann wie folgt aus:
Code :
1 2 3 4 5 6 7 8 9 10 11 | clear
# Variablen mit Werten fuellen
z1=10
[B]echo -n "Welche Zahl wollen Sie zu $z1 addieren: "
read z2
echo ""[/B]
echo "$z1 + $z2 ist `expr $z1 + $z2`!"
echo "" |
-- Übergabe von Werten beim Scriptaufruf --
Was wollen wir machen?- ganz wichtig für das effiziente Arbeiten mit Shellscripten ist das Übergeben von Argumenten
Es ist auch möglich mehrere Argumente zu übergeben und diese zu Mischen. Soll heißen:
sh Dateiname 10 Apfel ./bla.txt
Wir erinnern uns an das Script, das uns aufforderte unseren Namen einzugeben.
Wir modifizieren den Code, so dass wir den Namen beim Script-Aufruf mit übergeben.
Code :
1 2 | touch 04_argumente
vi 04_argumente |
Code :
1 2 3 | clear
echo "Mein Name ist $1." |
Auf diese Weise haben wir die Möglichkeit an den Inhalt der übergebenen Argumente zu kommen.
Wichtig!
Bei der Übergabe des Namens, darf dieser kein Leerzeichen beinhalten, da dieser Name dann schon als zwei Argumente Interpretiert würde. Das müssen wir uns merken!
Ein Beispiel, bei dem wir unseren Namen, gefolgt von zwei Zahlen, die miteinander multipliziert werden, mit übergeben.
Dazu öffnen wir wieder '04_argumente' und passen dieses an die neuen Anforderungen an.
Code :
1 2 3 4 | clear
echo "Hallo $1. Das Ergebnis ist `expr $2 \* $3`."
echo "" |
Code :
1 | sh 04_argumente Hans 5 3 |
Code :
1 | Hallo Hans. Das Ergebnis ist 15. |
Das ist notwendig, da es sich um ein spezielles Zeichen handelt (Meta-Zeichen für Dateinamen), das als solches benutzt werden soll.
Ein kleines Beispiel dazu. Der Text, der bei dem Echo-Befehl ausgegeben wird, steht in Anführungszeichen.
Jetzt wollen wir, dass der Name, den wir mit übergeben, bei der Ausgabe auch in Anführungszeichen steht und ändern desshalb unser Script noch ein ganz klein wenig ab.
Code :
1 2 3 4 | clear
echo "Hallo \"$1\". Das Ergebnis ist `expr $2 \* $3`."
echo "" |
Wenn wir alles richtig gemacht haben, erscheint, wenn wir das Script wie eben mit Hans, 3, 5 aufrufen:
Code :
1 | Hallo "Hans". Das Ergebnis ist 15. |
- der ein oder andere wird sich vielleicht gefragt haben, warum das erste Argument mit $1 angesprochen wird und ob $0 ggf. auch eine Verwendung hat.
Richtig! $0 repräsentiert den Namen des aktuellen Shellscripts.
Die Argumente finden sich in den Variablen $1 ... $9 wieder.
An alle Argumente auf einen Schlag kommen wir mit $*
Es gibt noch ein paar weitere Befehle, aber die sollen uns jetzt noch nicht interessieren.
Einzig $# ist noch interessant, um die Anzahl der übergebenen Argumente zu ermitteln.
Was wollen wir machen?- um Kontrollstrukturen kommt kein Programmierer drum herum. Auch nicht, wenn es sich um einfache Shellscripte handelt.
Aus diesem Grund fangen wir ganz leicht mit der Wenn-Dann-Abfrage an.
Eine if-Abfrage kann immer nur einen von maximal zwei Zuständen haben.
Trifft die Bedingung zu, ist der Rückgabewert 'wahr'.
Trifft die Bedingung nicht zu, ist der Rückgabewert 'false'.
Da wir aber programmieren und uns somit im Englischen bewegen... true und false!
Als erstes wollen wir aber wissen, ob 10 größer ist als 8.
Zugegeben, es scheint sich um eine recht simple, wenn nicht sogar dämliche, Fragestellung zu handeln. Dennoch eignen sich derartige einfachen Beispiele die if-Abfrage näher zu bringen.
Um jetzt die Datei anzulegen ist es Zeit eine weitere Möglichkeit kenn zu lernen, eine Datei anzulegen und sich den touch-Befehl zu sparen.
Wir tippen vi gefolgt von dem gewünschten Script-Namen ein und bestätigen mit der Enter-Taste.
Code :
1 | vi 05_zahlen_vergleichen |
Der Code, den wir jetzt eingeben werden, überprüft den Wert aus Variable 1 mit dem aus Variable 2 und sagt uns, wenn der Wert größer ist.
Code :
1 2 3 4 5 6 7 8 | clear
z1=10
z2=8
if [ $z1 > $z2 ]
then[INDENT]echo "$z1 ist groesser als $z2."[/INDENT]else[INDENT]echo "$z1 ist kleiner oder gleich $z2."[/INDENT]fi
echo "" |
Man kann aber viele Fehler machen. Sowohl bei der Syntax (also wie man die Abfrage tippen muss), als auch bei der Logik kann man ganz schnell ungewollte und die wirrsten Ergebnisse bekommen.
Bei der Syntax ist zu beachten, dass vor und hinter jedem "[" und "]" ein Leerzeichen steht, da es sonst zu ungewollten Fehlern kommt.
Desweiteren ist zu beachten, dass unter dem "if" ein "then" steht, welches nicht in der gleichen Zeile wie die Abfrage selber stehen darf.
Eine ganz wichtige Sache ist das Einrücken von Zeilen. Ich empfehle jeweils immer zwei Leerzeichen. Das sollten wir uns schnellst möglichst angewöhnen und auch einhalten. Wenn wir später 5 bis 10 Schleifen und Abfragen verschachteln, würden wir ansonsten durch deren Aufbau nicht mehr durchsteigen.
Auch wenn Sie den Sinn nicht auf Anhieb verstehen, lege ich Ihnen trotzdem ans Herz den Ratschlag zu befolgen.
Abgeschlossen wird die Abfrage mit "fi" (if umgedreht). Ob das nun so schön ist, darüber lässt sich streiten. Es ist einfach so.
Ist $z1 größer als $z2, werden alle Befehle nach dem 'then' abgearbeitet. Ist $z1 genau so groß wie $z2 oder kleiner, wird der else-Zweig verarbeitet.
Um nun sicher zu wissen, ob die $z2 auch wirklich kleiner (nennt man: echt kleiner) ist, müssen wir eine weitere Abfrage in den else-Zweig einbinden. Wir sprechen dann von einer Verschachtelung.
Dazu kommen wir noch einmal, wenn wir es brauchen.
Erst mal vergleichen wir jetzt zwei Strings (Zeichenfolgen) in einem weiteren Script miteinander.
Code :
1 | vi 05_strings_vergleichen |
Code :
1 2 3 4 5 | clear
if [ $1 == $2 ]
then[INDENT]echo "Die beiden Zeichenfolgen sind identisch."[/INDENT]else[INDENT]echo "$1 unterscheidet sich von $2!"[/INDENT]fi
echo "" |
Bsp.:
Code :
1 | sh 05_strings_vergleichen Apfel Birne |
Wann verwenden wir ein '=' und wann '=='?
- '=' verwenden wir bei einer Wertzuweisung.
Bsp: wert1=10 - '==' wird verwendet, wenn der Inhalt zweier Werte auf Gleichheit geprüft wird.
Tipp: Ungleich würde man mit '!=' prüfen!
Code :
1 2 3 4 5 6 7 8 9 10 | clear
if [ $1 == $2 ]
then[INDENT]echo "Die beiden Zeichenfolgen sind identisch."[/INDENT]else[INDENT]echo "$1 unterscheidet sich von $2!"[/INDENT]fi
echo ""
<b># Auf ungleich prüfen
vergl=blubb
if [ $1 != $2 ]
then[INDENT]echo "Ja, $1 ist nicht identisch mit $vergl."[/INDENT]else[INDENT]echo "$1 ist identisch mit $vergl."[/INDENT]fi
echo ""</b> |
Nur wenn diese beiden Strings identisch sind, wird der else-Zweig verarbeitet.
Ein weiteres Anwendungsbeispiel.
Code :
1 | vi 05_wurde_argument_uebergeben |
Code :
1 2 3 4 5 6 7 | clear
# prüfen, ob ein Argument übergeben wurde
if [ $# == 0 ]
then[INDENT]echo "Es wurde kein Name angegeben."
echo "Der Name muss beim Scriptaufruf als Argument mit übergeben werden."[/INDENT]else[INDENT]echo "Mein Name ist $1"[/INDENT]fi
echo "" |
Ist der Wert nicht 0, wird der else-Zweig ausgeführt und in unserem Beispiel der Satz "Mein Name ist xyz" ausgegeben.
Eine Anmerkung noch!
Nur weil wir hier nur echo-Befehle in den Abfragen benutzt haben, bedeutet das nicht, dass nichts Anderes möglich sei. Die Möglichkeiten sind da nahezu unbegrenzt, wie wir im Weiteren auch noch sehen werden.
-- test testen --
Was wollen wir machen?- dieses Kapitel widmet sich dem test.
Unix bietet uns ein Werkzeug mit dem Namen 'test'. Dies ist auch der Grund, warum ich davon abrate, einer Datei den Dateinamen 'test' zu geben!
Mit test lassen sich die verschiedensten Dinge abprüfen. Einige von den vielen vielen Möglichkeiten schauen wir uns mal genauer an.
Wir haben es eben sogar schon benutzt! An Stelle von
Code :
1 | if [ $1 != $vergl ] |
Code :
1 | if test $1 != $vergl |
Um uns mal einen Überblick zu verschaffen, welche Möglichkeiten uns das Werkzeug so gibt, geben wir in der Konsole mal
Code :
1 | man test |
Wie wir sehen, bietet test uns jede Menge Möglichkeiten.
Also, los geht's...
Code :
1 | vi 06_test_anwenden01 |
Code :
1 2 3 4 5 6 7 | clear
echo -n "Bitte geben Sie Ihre Lieblings-Obstsorte ein: "
read obst
if test -z $obst
then[INDENT]echo "Sie haben keine Obstsorte angegeben."[/INDENT]else[INDENT]echo "So so, Sie mögen also gerne $obst."[/INDENT]fi
echo "" |
Ist dies der Fall, wird true, ansonsten false zurückgegeben.
Probieren wir beides aus. Wir starten das Script
Code :
1 | sh 06_test_anwenden01 |
Geben wir hingegen beispielsweise 'Apfel' ein, ist der Rückgabewert von test false, da die Zeichenlänge ja nicht 0 ist, und somit wird der else-Zweig bearbeitet.
In der Manual zu test haben wir ja auch gelesen, dass sich dieses Werkzeug wunderbar dazu eignet um Dinge rund um Dateien abzufragen.
Wir werden uns an dieser Stelle noch nicht darum kümmern, sondern kommen an gegebender Stelle darauf zurück.
-- Schleifen --
Was wollen wir machen?- wir sind wieder bei Kontrollstrukturen und nehmen uns jetzt die erste (und später noch eine zweite) Schleife vor
Neuer Abschnitt, also erst mal eine neue Datei:
Code :
1 | vi 07_meine_erste_schleife |
x = 1
x = 2
x = 3
x = 4
x = 5
x = 6
x = 7
x = 8
x = 9
x = 10
x = 2
x = 3
x = 4
x = 5
x = 6
x = 7
x = 8
x = 9
x = 10
Solange x <= 10, addiere 1 zu x.
Code :
1 2 3 4 5 6 7 | clear
x=1
while [ $x -le 10 ]
do[INDENT]echo "x = $x"
x=`expr $x + 1`[/INDENT]done
echo "" |
Wir erinnern uns, dass bei einer Wertzuweisung das $-Zeichen weggelassen werden muss.
Jetzt geht es in die Schleife. Eröffnet wird sie mit "while" und den eckigen Klammern. Auch hier ist es wieder wichtig, dass vor und nach den Klammern Leerzeichen sind.
Code :
1 | $x -le 10 |
Nach der Bedingung folgt das Schlüsselwort "do", welches den auszuführenden Teil einleitet.
Der Part, der während des Schleifendurchlaufs ausgeführt werden soll, sollte wieder unbedingt eingerückt werden (auch hier empfehle ich zwei Leerzeichen).
Was tut unsere Schleife denn da überhaupt?
Code :
1 2 | do[INDENT]echo "x = $x"
x=`expr $x + 1`[/INDENT] |
Danach wird x mit dem Werkzeug 'expr' das wir ja schon kennen, um einen erhöht. Das ist ganz wichtig, da die Schleife sonst NIE enden würde, nur der Rechner irgendwann alle Viere von sich streckt und neugestartet werden müsste.
Wenn wir allerdings doch mal in so einer Endlosschleife hängen, können wir diese, und auch jeden anderen Programm-Ablauf, mit der Tastenkombination STRG+C (oder CTRL+C) abwürgen.
Der Dateiname unseres Scriptes hat es uns eigentlich schon verraten,... wir werden noch eine weitere Schleife basteln. Da es sich um eine Schleife handelt, die sich von while-Schleife unterscheidet, werden wir ihr eine neue Datei gönnen.
Code :
1 | vi 07_for_schleife |
Man könnte sagen, die for-Schleife kommt zum Einsatz, wenn die Anzahl der Durchläufe bekannt ist.
Wir dürfen nicht verzweifeln, wenn wir bei unseren ersten Versuchen die falsche Schleife anwenden, zum Ziel kommt man oft trotzdem.
Jetzt aber los! Wir wollen ein Script, dem beim Aufruf mehrere Variablen übergeben werden können.
Eben haben wir gesagt, dass sich eine for-Schleife eignet, wenn wir wissen, wie viele Durchläufe wir haben werden.
Wir erinnern uns, dass wir mit $# abprüfen können, wie viele Argumente beim Scriptaufruf übergeben wurden, also wissen wir, wie oft die Schleife durchlaufen werden muss, um alle Argumente wieder auf dem Bildschirm auszugeben.
Code :
1 2 3 4 5 6 7 | clear
echo Uebergabeparameter: $*
for i in $*
do[INDENT]echo Hier steht: $i[/INDENT]done
echo "" |
Code :
1 | sh 07_for_schleife 2 4 6 8 10 |
Code :
1 2 3 4 5 6 | Uebergabeparameter: 2 4 6 8 10
Hier steht: 2
Hier steht: 4
Hier steht: 6
Hier steht: 8
Hier steht: 10 |
An Stelle der Ausgabe, kann natürlich auch jede andere Aktion mit dem Argument gemacht werden!
-- Erstes kleines Programm --
Was wollen wir machen?- jetzt wollen wir unser neues Wissen mal anwenden, aber auch hier, werden wir immer wieder über Neues stolpern. Aber das kriegen wir schon hin!
Doch erst mal ein paar Vorbereitungen.
Legen wir erst mal eine Namensliste an. Womit? Na klar, mit dem vi!!

Code :
1 | vi nameliste.txt |
Code :
1 2 3 4 | Heinz Oldmann
Semi Kolon
Ellen Bogen
Willi Walter |
Nachdem wir die obrige Namensliste erstellt und den vi wieder verlassen haben, versuchen wir uns einmal an folgendem Befehl:
Code :
1 | grep Ellen namenliste.txt |
Code :
1 | Ellen Bogen |
Nun aber zu unserem Programm. Fangen wir ganz einfach und unkompliziert an.
Code :
1 | vi 08_erstes_kleines_programm |
Code :
1 2 3 4 5 6 7 8 9 10 11 12 | clear
echo -n "Bitte geben Sie den zu suchenden String ein: "
read suche
echo ""
echo "Suchergebnis:"
echo ""
echo ""
echo "`grep $suche $1`"
echo "" |
Code :
1 | sh 08_erstes_kleines_programm namenliste.txt |
Gäbe es noch einen weiteren Namen, der 'Ellen' enthält, würden beide Suchergebnisse untereinander ausgegeben.
Folgendes steht auf dem Programmplan:
- die Anzahl der Suchergebnisse sollen angezeigt werden
"Suchergebnis:" ersetzen mit "x Einträge gefunden", wobei x für die Anzahl der gefundenen Einträge steht - logisch! - es soll überprüft werden, ob überhaupt eine Datei als Argument übergeben wurde
- wenn ja, ob es sich wirklich um eine lesbare Datei handelt
- die Möglichkeit schaffen, zwei, oder mehr, Namenslisten anzugeben
Code :
1 2 3 4 5 6 7 8 9 10 11 12 | clear
echo -n "Bitte geben Sie den zu suchenden String ein: "
read suche
echo ""
[B]echo "`grep -c $suche $1` Eintraege gefunden:"[/B]
echo ""
echo ""
echo "`grep $suche $1`"
echo "" |
Prüfen wir nun ab, ob überhaupt ein Argument mit übergeben wurde.
Eine Variable hat uns ihre Hilfe angeboten und die nehmen wir gerne an.
In dieser Variable, mit dem Namen 'doit', werden wir eine 0 schreiben, wenn kein, und eine 1, wenn doch ein Argument übergeben wurde.
Und zwar prüfen wir das noch bevor wir unseren Suchstring eingeben, da das ja unnötig wäre, wenn eh keine Datei zum drin suchen angegeben wurde.
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | clear
if [ $# == 0 ]
then[INDENT]doit=0
echo "Es wurde keine Namensliste angegeben!"
[/INDENT]else[INDENT]doit=1[/INDENT]fi
if [ $doit == 1 ]
then[INDENT]echo -n "Bitte geben Sie den zu suchenden String ein: "
read suche
echo ""
echo "`grep -c $suche $1` Eintraege gefunden:"
echo ""
echo ""
echo "`grep $suche $1`"[/INDENT]fi
echo "" |
Was aber, wenn man statt "namenliste.txt" einfach eine Zahl, oder anderen Unsinn, angibt?
Dumm gelaufen! Und darum werden wir die Abfrage erweitern, dass zusätzlich gefragt wird, ob das Argument eine lesbare Datei ist. Das Werkzeug test wird uns behilflich sein und aus der Manual wissen wir, dass '-r' genau das bei einer Datei abprüft, was wir wissen wollen.
Wenn also überhaupt ein Argument übergeben wurde, dann prüfen wir, ob es sich um eine existierende und lesbare Datei handelt und nur dann geht es weiter im Programm:
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | clear
if [ $# == 0 ]
then[INDENT]doit=0
echo "Es wurde keine Namensliste angegeben!"
[/INDENT]else[INDENT]# eine if-Abfrage im else-Zweig einer anderen Abfrage
if test -r $1 # wenn Datei existiert und lesbar ist
then[INDENT]doit=1[/INDENT]else[INDENT]doit=0
echo "Datei \"$1\" existiert nicht, oder ist nicht lesbar."[/INDENT]fi
[/INDENT]fi
if [ $doit == 1 ]
then[INDENT]echo -n "Bitte geben Sie den zu suchenden String ein: "
read suche
echo ""
echo "`grep -c $suche $1` Eintraege gefunden:"
echo ""
echo ""
echo "`grep $suche $1`"[/INDENT]fi
echo "" |
Jetzt sehen wir auch, warum es sich gelohnt hat, die Abfrage nicht direkt in die unterste if-Abfrage einzubauen, sondern sie gesondert zu behandeln. Es würde gehen, aber so ist es übersichtlicher und kompfortabler und vor allem leichter erweiterbar, wie im nächsten Kapitel!
Bevor wir unser Script noch erweitern, muss es erst noch getestet werden.
Um es auch an einer nicht lesbaren Datei zu testen, werden wir diese jetzt anlegen und das Leserecht nehmen.
Code :
1 | touch nicht_lesbar |
Code :
1 | chmod 333 nicht_lesbar |
Code :
1 | Datei "nicht_lesbar" existiert nicht, oder ist nicht lesbar. |
Was wollen wir machen?- unser kleines Progrämmchen bekommt jetzt seinen Feinschliff. Mit dem erlernten Wissen um die Anwendung von Schleifen, werden wir uns eine davon schnappen um den Benutzer unseres Scriptes die Möglichkeit zu geben, mehr als ein Argument zu übergeben
- die Anzahl der Suchergebnisse sollen angezeigt werden
"Suchergebnis:" ersetzen mit "x Einträge gefunden", wobei x für die Anzahl der gefundenen Einträge steht - logisch! - es soll überprüft werden, ob überhaupt eine Datei als Argument übergeben wurde
- wenn ja, ob es sich wirklich um eine lesbare Datei handelt
Der Befehl dazu ist 'cp' gefolgt von der zu kopierenden Datei und dem Zielnamen:
(ich erinnere noch mal an die Möglichkeit der Autovervollständigung der Datei-Namen durch die TAB-Taste!!)
Code :
1 | cp 08_erstes_kleines_programm 08_erstes_kleines_programm_teil2 |
Code :
1 | vi 08_erstes_kleines_programm_teil2 |
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | clear
if [ $# != 0 ] # wenn ueberhaupt ein Argument uebergeben wurde
then[INDENT]echo -n "Bitte geben Sie den zu suchenden String ein: "
read suche
for i in $* # alle Argumente der Reihe nach ansprechen
do[INDENT]if test -r $i # existiert Datei und ist lesbar?
then[INDENT]echo ""
echo "`grep -c $suche $i` Eintraege in \"$i\"."
echo ""
echo "`grep $suche $i`"
[/INDENT]fi
[/INDENT]done[/INDENT]else[INDENT]echo "Es wurde keine Datei zum Suchen mit uebergeben!"[/INDENT]fi
echo "" |
In der ersten If-Abfrage prüfen wir, ob denn überhaupt ein Argument, also eine Datei, übergeben wurde. Ist dies nicht der Fall, kommt eine entsprechende Meldung und unser Script ist schon am Ende.
Wurde aber doch mindestens eine Datei angegeben, so wird im nächsten Schritt nach dem zu suchenden String gefragt. Wir geben diesen ein und es geht in die For-Schleife (auch Zählschleife genannt). Diese arbeitet nun alle übergebenen Dateien ab. Wenn nur eine Datei übergeben wurde, wird auch nur eine abgearbeitet. Bei zwei, hat die Schleife zwei Durchläufe.
Das wollen wir doch mal testen.
Wir haben ja bereits die Datei "namenliste.txt". Kopieren wir diese doch einfach...
Code :
1 | cp namenliste.txt namenliste2.txt |
Wie rufen wir unser Script denn jetzt mit zwei Argumenten auf? Nichts leichter als das:
Code :
1 | sh 08_erstes_kleines_programm_teil2 namenliste.txt namenliste2.txt |
Fertig!

-- 6 aus 49 --
Was wollen wir machen?- Lottozahlen generieren!
Und warum? Na ja. Zum Einen, weil das in fast jedes Beginner-Tut gehört und weil ich danach gefragt wurde.

Kein Müdigkeit vortäuschen...
Code :
1 2 3 | touch 09_lotto
vi 09_lotto |
Weil es mit der Zeit jetzt ein wenig unübersichtlich wird, werde ich ab jetzt, wo es sich anbietet, statt des Kommentars eine Zahl anfügen und unter dem Quellcode erläutern, was an Stelle des Kommentars dort steht.
Code :
1 2 3 4 5 6 7 8 9 10 | clear
echo `touch lotto_temp` # 1
i=0
while [ $i -lt 6 ] # 2
do[INDENT]rnd=$((RANDOM % 49 + 1)) # 3
echo $rnd >> lotto_temp # 4
i=`expr $i + 1`[/INDENT]done
echo `sort -n lotto_temp` # 5
echo `rm lotto_temp` # 6 |
- temporäre Datei zum Zwischenspeichern der Zahlen anlegen
- solange i kleiner 6 ist
- Zufallszahl ermitteln und in Variable 'rnd' schreiben
(durch das '% 49 + 1' stellen wir sicher, dass nur Zahlen im gewünschten Bereich gewählt werden - das '%' steht in diesem Fall für Modulo) - die Zufallszahl in die temporäre Datei schreiben
(das '>>' bedeutet, dass die Datei angehängt wird. Ein '>' würde bewirken, dass evtl. schon drin stehende Zahlen einfach überschrieben würden) - Diese Zeile könnten wir auch auslassen. Allerdings würde unsere Ausgabe dann nicht sortiert ausgegeben, sondern quer durcheinander.
Bei dem 'sort'-Befehl bewirkt das -n, dass nummerisch Sortiert wird, was für unser Beispiel genau das richtige ist, da es sich ja um Zahlen handelt.
Der 'sort'-Befehl ist hier auch dafür zuständig, dass die Ziffern auf dem Bildschirm ausgegeben werden. - rm --> remove
Wir löschen die anfangs angelegte Datei, denn sie ist schließlich temporär und wird nicht weiter benötigt.
Das gehört geändert.
Und genau darum kümmern wir uns jetzt.
Da wir geschachtelte Schleifen mögen, werden wir jetzt einfach eine weitere Schleife einbauen, die solange eine neue Zufallszahl anfordert, bis eine gefunden wurde, die noch nicht in der 'lotto_temp' steht.
Neue / geänderte Zeilen sind wieder fett abgebildet.
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 | clear
echo `touch lotto_temp`
[B]rnd=$((RANDOM % 49 + 1))[/B]
i=0
while [ $i -lt 6 ]
do[INDENT][B]while [ `grep -c $rnd lotto_temp` -gt 0 ]
do[INDENT]rnd=$((RANDOM % 49 + 1))[/INDENT]done
[/B]echo $rnd >> lotto_temp
i=`expr $i + 1`
[/INDENT]done
echo `sort -n lotto_temp`
echo `rm lotto_temp` |
Das '-gt' steht für 'greater than / größer als' (nicht größer/gleich als!!)
So wird so lange eine neue Zufallszahl angefordert, bis die Anzahl = 0 ist und wir haben fortan keine Duplikate mehr.
Viel Glück bei der nächsten Ziehung!

-- Lock-Screen --
Was wollen wir machen?- Unsere Konsole, und damit unser System, vor dem Zugriff Unbefugter schützen.
Jetzt nicht gleich das Browser-Fenster schließen! Klingt komplizierter als es ist.
Code :
1 2 3 | touch 10_lockscreen
vi 10_lockscreen |
Nun wäre es strategisch unpraktisch, wenn das PW beim Festlegen lesbar auf dem erscheinen würde.
Deshalb schauen wir mal, wie wir das umgehen können. Das Werkzeig 'stty' hilft uns.
Es ermöglicht es die Eingabe unsichtbar geschehen zu lassen.
Code :
1 | stty -echo |
Code :
1 2 3 4 5 6 | echo -n "PW eingeben: "
stty -echo
read CODE
stty echo
echo ""
echo "Ihr PW: $CODE" |
Wir stellen fest, dass sich der Cursor sich nicht von der Stelle bewegt. So kann niemand, der einem über die Schulter guckt, die Zeichenanzahl unseres PWs erkennen.
Nachdem wir unsere Eingabe, wie gewohnt, mit ENTER bestätigen, wird unser PW ausgegeben.
Sicher, das ist sinnfrei!
Aber es handelt sich hier ja nur um ein Beispiel.Löschen wir die unteren beiden Zeilen (im vi in die entsprechende Zeile gehen und zwei mal die 'd'-Taste drücken).
Code :
1 2 3 4 5 6 7 | echo -n "PW eingeben: "
stty -echo
read CODE
stty echo
clear
MATCH=""
DELAY=1 |
In der Variable 'MATCH' erfassen wir später die PW-Eingaben.
Wir werden unserem Script einen kleinen Leckerbissen verpassen. Nach jeder falschen Eingabe, wird die Wartezeit auf die nächste Eingabe verdoppelt.
Den Startwert von 1 weisen wir der Variable 'DELAY' zu.
Jetzt kümmern wir uns um die Schleifenbedingung:
Code :
1 2 | while [ "$MATCH" != "$CODE" ]
do |
Was packen wir jetzt in den Schleifenkörper?
- die Warteanweisung
- die Verdopplung der Wartezeit
- die Eingabe des Passworts
Code :
1 2 3 4 5 | while [ "$MATCH" != "$CODE" ]
do[INDENT]sleep $DELAY
echo -n "Bitte Passwort eingeben: "
read MATCH
DELAY=`expr $DELAY \* 2`[/INDENT]done |
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | echo -n "Bitte Passwort festlegen: "
stty -echo
read CODE
stty echo
clear
MATCH=""
DELAY=1
while [ "$MATCH" != "$CODE" ]
do[INDENT]sleep $DELAY
echo -n "Bitte Passwort eingeben: "
read MATCH
DELAY=`expr $DELAY \* 2`[/INDENT]done
echo |
Dafür zuständig ist die Zeile
Code :
1 | DELAY=`expr $DELAY \* 2` |
Na gut, noch mal ganz kurz: Der Benutzer wird aufgefordert ein Passwort einzugeben und seine Eingabe wird der Variable 'MATCH' zugewiesen.
Rufen wir das Script mal auf:
Code :
1 | sh 10_lockscreen |
Geben wir das richtige ein, können wir weiterarbeiten.
Wir haben bei unseren Schleifen-Scripten die Möglichkeit kennen gelernt, mit der Tastenkombination "STRG + C" einen Ablauf abzubrechen.
Oh, was ist das? Das geht hier ja auch - sehr ungünstig!
Also müssen wir noch mal ran.
Eine andere,... nennen wir es erst mal Oberfläche, erlaubt es uns die Tastenkombination zu unterbinden.
Den Aufruf dieser anderen Bash erreichen wir wie folgt mit dem Werkzeug 'trap'
Die in unser vorhandenes Script einzufügende Zeile ist fett gedruckt
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | echo -n "Bitte Passwort festlegen: "
stty -echo
read CODE
stty echo
clear
[B]trap "" 2 3[/B]
MATCH=""
DELAY=1
while [ "$MATCH" != "$CODE" ]
do[INDENT]sleep $DELAY
echo -n "Bitte Passwort eingeben: "
read MATCH
DELAY=`expr $DELAY \* 2`[/INDENT]done
echo |
-- Idealgewicht --
Was wollen wir machen?- Unser Idealgewicht (berechnen)
- ein bisschen Wiederholung
Code :
1 2 3 | touch 11_idealgewicht
vi 11_idealgewicht |
- Mann
kg = (Körpergröße in cm - 100) * 0,9 - Frau
kg = (Körpergröße in cm - 100) * 0,85
Vom Benutzer benötigen wir die Eingabe von Körpergröße (in cm) und das Körpergewicht (in kg)
Code :
1 2 3 4 5 6 7 | clear
echo -n "Bitte geben Sie Ihre Körpergröße in cm ein: "
read groesse
echo -n "Bitte geben Sie Ihr Gewicht ein: "
read gewicht |
Als erstes ziehen wir die 100 von der Körpergröße ab und speichern das Ergebnis schon mal in der Variable für das Idealgewicht.
Zur Berechnung benutzen wir wieder unser Werkzeug 'expr' - klar, oder?
Code :
1 | ideal=`expr $groesse - 100` |
Ach, ist gar kein Problem. Als mathematisch versierte Scripter erkennen wir sofort folgenden Lösungsweg:
Wir multiplizieren mit 9 und dividieren anschließend durch 10.
Code :
1 2 | ideal=`expr $ideal \* 9`
ideal=`expr $ideal \/ 10` |
Code :
1 2 | echo ""
echo "Ihr Idealgewicht wäre $ideal kg." |
Dazu berechnen wir im ersten Schritt die Differenz
Code :
1 | differenz=`expr $gewicht - $ideal` |
Code :
1 2 3 | if [ $differenz -gt 0 ]
then[INDENT]echo "Sie haben Übergewicht: $differenz kg."[/INDENT]else
fi |
Es wird geprüft, ob die Differenz echt größer als 0 ist.
Ist dies nicht der Fall, geht es in den Else-Zweig, den wir jetzt füllen
Code :
1 2 3 4 | else
if [ $differenz -lt 0 ][INDENT]then[INDENT]differenz=`expr $differenz \* -1`
echo "Sie haben Untergewicht: $differenz kg."
[/INDENT]else[INDENT]echo "Sie haben Idealgewicht!"[/INDENT]fi[/INDENT]fi |
Trifft das nicht zu, kann nur noch ein Fall eintreten, der Else-Zweig wird aufgerufen.
Rufen wir das Script mal auf:
Code :
1 | sh 11_idealgewicht |
Das war es für's erste...
Über Verbesserungsvorschläge oder Bemerkungen anderer Art würde ich mich freuen (besonders wenn es jemandem gefallen hat
)MfG Kryp



Kommentar schreiben

Bereiche
Kategorien
Forum - Computer & Devices





Artikel bewerten