Grundlagen der Shellskript-Programmierung

Ähnliche Dokumente
Bash-Skripting Linux-Kurs der Unix-AG

Bash-Skripting Linux-Kurs der Unix-AG

Shell-Scripting Linux-Kurs der Unix-AG

Shell-Scripting Linux-Kurs der Unix-AG

Übersicht Shell-Scripten

Bash-Scripting Linux-Kurs der Unix-AG

Shell-Scripting Linux-Kurs der Unix-AG

Computer & GNU/Linux Einführung Teil 4

Shell-Scripting Linux-Kurs der Unix-AG

Arithmetik in der tcsh

Skripte. Beispiel. M. Fyta Computergrundlagen 73/93

Allgemeines. Shell Programmierung Unix. Kommentar. Vorgangsweise. Mag. Thomas Griesmayer

Vorbemerkung. Allgemeines zu Shell Scripts. Aufruf. Einfaches Beispiel

Systemverwaltung mittels Skripts

Alles, was man auf der Kommandozeile eingeben kann, kann man auch in einem Skript verwenden. Umgekehrt gilt das gleiche.

Linux und Shell-Programmierung Teil 6

Die Shell. Ein Vortrag von Frederik und Michael 1 / 35

Schleifen: Immer wieder dasselbe tun

Übersicht PERL. !!!! Wichtig: Nach dem Befehl einem Strichpunkt setzen!!!!

Vorlesung Unix-Praktikum

Technische Praxis der Computersysteme 1

Okt 10, 16 17:29 UNIX/Linux Lösung

Shell-Programmierung

Shell-Programmierung fur Unix und Linux

Linux und Shell-Programmierung Teil 5

Arzu Sanli Ibrahim Canakci

Linux Kommandozeile: Einfache Skripte. 1 Wiederhohlung. 2 Einfache Skripte

Arbeiten mit der Shell Teil 2

Vorlesung Unix-Praktikum

Linux Prinzipien und Programmierung

Unix-Grundkurs 1. Thema heute: Shell-Skripten

Vorlesung Unix-Praktikum

Crashkurs Kommandozeile

Shell. Oder Konsole suchen im Application Finder. Auch Terminal, Bash oder Kommandozeile genannt. Bash nimmt Befehle entgegen und führt diese aus

Shell-Skript-Programmierung

Grundlagen der Programmierung

Linux II. Reguläre Ausdrücke Editoren Scripting. 2 Linux II. Linux I II III Res WN/TT NLTK XML Weka E Reguläre Ausdrücke Editoren Scripting

Unix/Linux Grundlagen für Einsteiger

Luis Kornblueh. May 22, 2014

Eine Mini-Shell als Literate Program

Shell-Programmierung für Unix und Linux

Linux-Einführung Übung

C++ Teil 2. Sven Groß. 16. Apr IGPM, RWTH Aachen. Sven Groß (IGPM, RWTH Aachen) C++ Teil Apr / 22

Arrays. Arrays werden verwendet, wenn viele Variablen benötigt werden. Der Vorteil in Arrays liegt darin, dass man nur eine Variable deklarieren muss

Teil 1: Einführung in die Shell. Was ist die Shell? Wichtige Kommandos (1) Einführung in die Shell. Grundlagen der Shell-Programmierung

Patrick Ditchen 4. Auflage. Shell-Skript Programmierung. Inklusive CD-ROM

Korn-Shell: Einführung in Shellscripte 1. Übersicht: Einführung - 2. Die Kornshell im Detail - 3.Grundlagen der Programmierung

Einführung Unix Shell

JavaScript. Dies ist normales HTML. Hallo Welt! Dies ist JavaScript. Wieder normales HTML.

UNIX/Linux Lösung. Mär 14, 17 20:40 Seite 1/6. Prozeßsynchronisation (was ist das?, wo kommt es vor?, Beispiel?):

Übung 4: Schreiben eines Shell-Skripts

105.1 Shell, Scripting

Shellprogrammierung. Einführung in Linux. Antonia Blanke. Shellprogrammierung Die Linux Shell Besondere Zeichen Pipes Variablen Bedingungen und Tests

06 While-Schleifen. While-Schleifen 1/7 Wiederholung: Schleifen

Shell-Programmierung. von Rolf Schmidt für. LUG Frankfurt

Betriebssysteme I WS 2016/17. Prof. Dr. Dirk Müller. 5 Shell-Programmierung

Vorlesung Unix-Praktikum

Arbeiten mit der Shell Teil 2

Arbeiten mit der Shell Teil 2

Unix-Shells. mehrere Befehle in einer Zeile. bash: Grundlagen. Ein- und Ausgaben umlenken. Befehle: Dateien und Verzeichnisse (1)

1.1 Shellprozeduren. 1.2 einfachste Skript Beispiele

Schleifenanweisungen

Ein- und Ausgabeumlenkung

Shell-Skripte in Unix

Grundlagen. Wie sind PHP-Dateien aufgebaut?

Linux Tutorium. 12. Shellprogrammierung. Version vom :38:56

Technische Praxis der Computersysteme I 3. Vorlesung

Übung: Entwickeln eines Shell-Skripts

UNIX Shell-Programmierung

FACHHOCHSCHULE AUGSBURG Hochschule für Technik, Wirtschaft und Gestaltung

Programmieren I + II Regeln der Code-Formatierung

1 Aufgaben 1.1 Umgebungsvariable setzen: CLASSPATH

Objektorientierung. Marc Satkowski 20. November C# Kurs

Einführung in die Kommandozeile

05 For-Schleifen. For-Schleifen 1/7 Was ist eine Schleife?

15 Der AWK. (Aho, Weinberger, Kernighan)

Schachtelung der 2. Variante (Bedingungs-Kaskade): if (B1) A1 else if (B2) A2 else if (B3) A3 else if (B4) A4 else A

Java 8. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Oktober 2014 JAV8

Transkript:

Oliver Kreipl, Dorian Karnbaum, Marc Remolt Grundlagen der Shellskript-Programmierung Ein Webmasters Press Lernbuch Version 1.0.1 vom 3.6.016 Autorisiertes Curriculum für das Webmasters Europe Ausbildungs- und Zertifizierungsprogramm. www.webmasters-europe.org

Inhaltsverzeichnis Vorwort 11 1 Allgemeine Einführung 13 1.1 1. Benötigte Vorkenntnisse Technische Voraussetzungen 13 13 Einführung in die Shellskript-Programmierung 14.1.1.1.1..1.3..3.3.1.3..3.3.4.4.1.4..4.3.5 Wiederholung Umleitungen Pipes Kommandoverknüpfungen Kommandosubstitution Aufbau eines Shellskriptes Shellskripte als Folge von Shellkommandos Der Shebang Kommentare Ausführen eines Shellskriptes Skript als Parameter der Shell ausführen Skript direkt ausführen Ein Shellskript sourcen 14 14 15 15 16 16 16 17 18 18 18 18 19 0 3 Variablen und Zuweisungen in einem Shellskript 1 3.1 3. 3..1 3.. 3.3 3.3.1 3.3. 3.3.3 3.4 3.4.1 3.4. 3.4.3 3.5 3.5.1 3.5. 3.5.3 3.5.4 3.5.5 3.5.6 Variablenzugriff Methoden der Zuweisung Einfache Zuweisung Ausgabe eines Kommandos zuweisen Ausgeben von Variablen echo Bedeutung der Anführungszeichen bei echo Abgrenzung des Variablennamens Besondere Zuweisungen Stringverkettung Löschen von Variablen Zuweisung mit Standardwert Umgebungsvariablen Konzept $PWD $SHELL $LOGNAME $PATH $LANG 1 1 1 4 5 5 5 6 6 6 7 7 7 7 8

3.5.7 3.6 $RANDOM 8 9 4 Formatierte Ausgabe 30 4.1 4.1.1 4.1. 4. 4.3 Erweitertes echo Zeilenumbruch unterdrücken Erweiterte Formatierungen printf 30 30 31 3 3 5 Shell-Expansion und Strings 33 5.1 5.1.1 5.1. 5.1.3 5.1.4 5. 5..1 5.. 5.3 5.3.1 5.3. 5.3.3 5.3.4 5.4 Dateinamensexpansion *? [] @() Musterexpansion {a,b,c,d} {a..z} Stringbehandlung Länge eines Strings ausgeben Teilstrings nach Position ausschneiden Teilstrings nach Muster entfernen Suchen und ersetzen 33 33 34 35 35 36 36 37 37 37 37 38 40 41 6 Weitere Shellfunktionen 4 6.1 6. 6..1 6.. 6..3 6.3 6.3.1 6.3. 6.4 Blöcke set Anzeige aller Variablen und Funktionen Verhalten der Shell einstellen Parametervariablen setzen Berechnungen Ohne Rückgabe Mit Rückgabe 4 43 43 43 44 44 45 46 46 7 Eingabe und Parameter 47 7.1 7.1.1 7.1. 7.1.3 7.1.4 7.1.5 7. 7.3 Parameter an ein Shellskript übergeben Regeln bei der Übergabe Die Parametervariablen Weitere Spezialvariablen Mehr als neun Parameter verarbeiten Mit set Parametervariablen setzen Einlesen von Benutzereingaben mit read 47 47 47 48 49 49 50 5

8 Tests und Bedingungen 53 8.1 8. 8.3 8.4 8.5 8.6 8.7 8.8 Tests Die Spezialvariable $? Dateitests Zahlentests Stringtests und Stringvergleiche Schreibweise der Bourne-Shell Kommandotests 53 53 53 54 55 57 57 58 9 Verzweigungen 60 9.1 9. 9..1 9.. 9..3 9.3 9.4 Entscheidungen treffen if if-else if-elif-else case 60 60 60 61 6 64 66 10 Schleifen 68 10.1 10. 10..1 10.. 10..3 10.3 10.3.1 10.3. 10.4 Wiederholtes Ausführen von Codeblöcken Die while-schleife Eine while-schleife ohne Abbruch-Modifikator While zum zeilenweisen Einlesen einer Textdatei Die for-schleife Dynamisch erzeugte Listen 68 68 68 69 69 71 71 7 73 11 Ergänzende Linux-Kommandos 75 11.1 11. 11..1 11.. 11..3 11.3 11.3.1 11.3. 11.4 11.4.1 11.4. 11.5 11.6 Kommandos als Helfer head und tail head tail Zeilen in der Mitte einer Datei auslesen basename und dirname basename dirname cut Ausschneiden nach Zeichen Ausschneiden nach Feldern tr 75 75 75 76 76 77 77 77 78 78 79 80 81 1 Signalverarbeitung 8 1.1 1.1.1 Prozesse und Signale Signale senden mit kill 8 8

1.1. 1.1.3 1. 1..1 1.. 1.3 Wichtige Signale Die Spezialvariable $$ Signale einfangen mit trap trap Aufräumen bei Skriptende 8 83 84 84 84 85 13 Fortgeschrittene Parameterauswertung 86 13.1 13. 13.3 Einschränkungen der Parametervariablen Verarbeiten von Parametern mit getopts 86 87 89 14 Reguläre Ausdrücke 91 14.1 14. 14..1 14.. 14..3 14..4 14..5 14..6 14.3 14.3.1 14.3. 14.4 14.4.1 14.4. 14.4.3 14.5 14.6 14.6.1 14.6. 14.7 Konzept Metazeichen Zeilenanfang und Zeilenende Zeichenklassen Posix-Zeichenklassen Negation von Zeichenklassen Ein beliebiges Zeichen Auskommentieren von Sonderzeichen Quantoren Allgemeine Quantoren Spezielle Quantoren Klammern Quantifizierung ganzer Ausdrücke Alternationen Zwischenspeichern von Treffern Rückwärtsreferenzen egrep Optionen 91 9 9 9 93 94 94 94 95 95 95 96 96 96 97 97 99 99 100 101 15 Einführung in Sed und Awk 10 15.1 15.1.1 15.1. 15.1.3 15.1.4 15. 15..1 15.. 15..3 15.3 Sed Zeilen löschen Nur bestimmte Zeilen ausgeben Suchen und ersetzen Löschen Awk Feldtrenner ändern awk und reguläre Ausdrücke 10 10 103 104 105 105 105 106 107 110

Lösungen der Wissensfragen 11 Index 15

68 10 Schleifen 10 Schleifen In dieser Lektion lernen Sie wie Sie denselben Code mehrfach ausführen können. was Schleifen sind. was die while -Schleife ist. was die for -Schleife ist. was Endlosschleifen sind. 10.1 Wiederholtes Ausführen von Codeblöcken Vielleicht kennen Sie das Problem: Sie wollen im Prinzip denselben Code mehrfach ausführen, aber nicht den Code kopieren und mehrfach in dasselbe Skript schreiben. 10. Die while-schleife 10..1 Eine while -Schleife führt den Codeblock zwischen do und done so lange aus, wie die Bedingung hinter while wahr ist, also einen exit-status von 0 zurückgibt. Hier werden fast immer Tests verwendet. 1 while Testbedingung do 3 # Codeblock 4 done Codebeispiel 10.1 while_syntax.sh Sie müssen selbst dafür sorgen, dass die Bedingung irgendwann»falsch«zurückliefert. Meistens verändern Sie die Testumstände in dem Codeblock, der jedes Mal ausgeführt wird. 1 #!/bin/bash 3 zaehler=0 4 5 while (( zaehler < 10 )) 6 do 7 echo "Zahl: $zaehler" 8 (( zaehler++ )) 9 done Codebeispiel 10. while1.sh

10. Die while-schleife 69 oliver@frodo:~$ bash while1.sh Zahl: 0 Zahl: 1 Zahl: Zahl: 3 Zahl: 4 Zahl: 5 Zahl: 6 Zahl: 7 Zahl: 8 Zahl: 9 Der Test sollte Ihnen inzwischen keine Schwierigkeiten mehr bereiten. Er prüft, ob die Shellvariable $zaehler kleiner als 10 ist. In Zeile 8 wird eben diese Variable in jedem Durchlauf um eins erhöht, weswegen die Schleife auch abbricht, sobald die Variable den Wert 10 erreicht. Sorgen Sie dafür, dass die Testbedingung irgendwann scheitert, denn sonst läuft Ihre Schleife bis in alle Ewigkeit und Sie haben eine sogenannte Endlos-Schleife erzeugt. Es gibt seltene Fälle, wo Sie genau das brauchen, aber meistens ist es ein Fehler. 10.. Eine while-schleife ohne Abbruch-Modifikator Sie können mit einer while -Schleife zum auch auf das Eintreffen eines bestimmten Systemereignisses warten, zum, wenn eine Datei gelöscht wird. Das folgende Skript läuft so lange, bis die Datei /tmp/test.txt nicht mehr existiert, und gibt dann eine Meldung aus. 1 #!/bin/bash 3 while [ -f /tmp/test.txt ] 4 do 5 sleep 5 6 done 7 8 echo "Datei wurde gelöscht!" Codebeispiel 10.3 while.sh Sie sehen richtig, der Codeblock der while -Schleife tut nichts! Besonders auffällig ist, dass es keinen Abbruch-Modifikator gibt. Da es von äußeren Umständen, hier von der Existenz einer Datei abhängt, ob die Bedingung wahr ist, muss im Code-Block auch keine künstliche Veränderung herbeigeführt werden, wie es im letzten der Fall war. Falls Sie das Kommando noch nicht kennen: sleep wartet die angegebene Anzahl an Sekunden und setzt erst dann das Skript fort. Alle 5 Sekunden wird also die Testbedingung geprüft, und sobald die Datei gelöscht ist, wird die Schleife abgebrochen und das echo auf Zeile 8 ausgegeben. 10..3 While zum zeilenweisen Einlesen einer Textdatei Die while -Schleife in Kombination mit dem read -Kommando bietet eine sehr elegante Möglichkeit, Textdateien zeilenweise einzulesen. Da Sie diese Funktionalität ohnehin benötigen werden und das außerdem noch eine interessante neue Schreibweise zeigt, will ich Ihnen diesen Code nicht vorenthalten.

70 10 Schleifen 1 #!/bin/bash 3 while read zeile 4 do 5 echo "Zeile: $zeile" 6 done < /etc/passwd Codebeispiel 10.4 while_read.sh Auf den ersten Blick sieht das etwas verwirrend aus. Gehen wir also die einzelnen Punkte durch. Das Kommando read liest immer eine einzelne Benutzereingabe ein. Sobald der Benutzer RETURN drückt, merkt read, dass seine Aufgabe beendet ist. oliver@frodo:~$ read zeile Das ist eine Zeile oliver@frodo:~$ echo $zeile Das ist eine Zeile Nach dem Wort Zeile hat der Benutzer RETURN gedrückt und read hat sich sofort beendet. Neu für Sie ist nun, dass read eigentlich von der Standardeingabe liest. Statt von der Tastatur, kann read also auch aus einer Datei lesen, wenn Sie eine Umleitung < verwenden. Was passiert nun, wenn Sie den folgenden Code ausführen? Denken Sie erst einmal darüber nach, bevor Sie es ausprobieren. oliver@frodo:~$ read zeile < /etc/passwd oliver@frodo:~$ echo $zeile Als Ausgabe erhalten Sie nur die erste Zeile der Datei/etc/passwd, nicht ihren gesamten Inhalt. Da am Ende der ersten Zeile ein Zeilenumbruch steht (daher heißt es auch Zeile), beendet sich read schon an dieser Stelle, und der restliche Text geht verloren. Wenn Sie dieses read in einer Schleife verwenden, wie in dem gerade, wird read so oft aufgerufen, wie es Zeilen zum Abarbeiten gibt. Wenn read keine Zeile mehr erhält, legt es in $? einen Wert ungleich 0 ab, was zum sofortigen Ende der Schleife führt. Die letzte Besonderheit an dieser Schleife ist, dass die Eingabeumleitung am Ende des Blocks, also nach dem done, steht.... done < /etc/passwd. Hoffentlich nicht wirklich neu.

10.3 Die for-schleife 71 Intuitiv hätten Sie die Umleitung eher hinter das read geschrieben, nicht wahr? while read zeile < /etc/passwd... Das funktioniert aber leider nicht, da Sie die gesamte Datei an ein einziges read übergeben. Es wird also im ersten Durchlauf die erste Zeile an read übergeben, der Rest, wie eben erklärt, wird verworfen. Im zweiten Durchlauf wird an ein neues read wieder die gesamte Datei übergeben und wieder wird die erste Zeile verarbeitet. Das Spiel können Sie beliebig lange fortsetzen (außer, die Datei wird manuell gelöscht), denn Sie haben eine Endlosschleife gebaut, die auf ewig die erste Zeile von /etc/passwd ausgibt. Wenn Sie die Umleitung nach dem done einfügen, wird der Inhalt der Datei nur ein einziges Mal an den Schleifenblock übergeben, und read pickt sich jedes Mal die nächste Zeile heraus. Wenn Sie jetzt Kopfschmerzen haben, sind Sie nicht alleine. Ich habe auch eine Weile gebraucht, bis ich das Prinzip hinter den wenigen Zeilen wirklich verstanden hatte. Aber es ist nun mal der empfohlene Weg, eine Textdatei zeilenweise abzuarbeiten. Also müssen Sie ihn kennen und wissen, was hier passiert. 10.3 Die for-schleife Eine for-schleife auf der Shell arbeitet anders, als Sie es eventuell aus anderen Programmiersprachen gewohnt sind. 3 Sie durchläuft eine Liste von Werten und speichert den jeweils nächsten Wert in der angegebenen Variable. Die Liste ist eine Sammlung von beliebigen Werten, die durch Whitespace, also Leerzeichen, Tabulatoren oder Zeilenumbrüche getrennt sind. Auch hier können Sie den Trenner durch Verändern der Variable IFS an Ihre Bedürfnisse anpassen. 10.3.1 Die sieht folgendermaßen aus: 1 for variable in liste do 3 # Codeblock 4 done Codebeispiel 10.5 for_syntax.sh Die Schleife durchläuft für jedes Element von liste die Anweisungen zwischen do und done. In jedem Schleifendurchlauf wird variable der nächste Wert aus liste zugewiesen. Als Variable gilt jeder gültige Variablenname. 1 #!/bin/bash 3 namen='herbert Sandra Klaus Bettina Frank Claudia' 4 3. Sie könnte eher mit einer foreach -Schleife aus PHP verglichen werden.

7 10 Schleifen 5 for name in $namen 6 do 7 echo "Hallo $name" 8 done Codebeispiel 10.6 for1.sh oliver@frodo:~$ bash for1.sh Hallo Herbert Hallo Sandra Hallo Klaus Hallo Bettina Hallo Frank Hallo Claudia Achten Sie darauf, dass Sie in Zeile 5 bei der ersten Variable einen Wert zuweisen, also kein $ verwenden dürfen, und bei der zweiten auslesen, das $ also brauchen. 10.3. Dynamisch erzeugte Listen Die Liste nach in muss von Ihnen nicht unbedingt wörtlich geschrieben werden. Jedes Kommando, das eine derartige Liste erzeugt, ist hier erlaubt. Besonders häufig wird hier die Kommandosubstitution verwendet. 1 #!/bin/bash 3 for file in $(find /etc -type f > /dev/null) 4 do 5 if grep 'root' $file > /dev/null >&1 6 then 7 echo "Der Begriff 'root' wurde in $file gefunden." 8 fi 9 done Codebeispiel 10.7 for.sh oliver@frodo:~$ bash for.sh Der Begriff 'root' wurde in /etc/skel/.bashrc gefunden. Der Begriff 'root' wurde in /etc/bash.bashrc gefunden. Der Begriff 'root' wurde in /etc/logrotate.d/dpkg gefunden. Der Begriff 'root' wurde in /etc/logrotate.d/apache gefunden. Der Begriff 'root' wurde in /etc/init.d/umountroot gefunden.... Der Begriff 'root' wurde in /etc/postfix/post-install gefunden. Der Begriff 'root' wurde in /etc/postfix/postfix-script gefunden. Der Begriff 'root' wurde in /etc/postfix/master.cf gefunden. Der find -Befehl gibt alle Dateien (ohne die Verzeichnisse selbst) unterhalb von /etc zurück, und diese Ausgabe wird als Liste an die for -Schleife übergeben. In jedem Durchlauf enthält $file also einen Dateinamen mit Pfad, z. B. /etc/passwd. In Zeile 5 wird in dem Codeblock der for -Schleife eine if -Anweisung ausgeführt. Dort wird mittels grep getestet, ob in der angegebenen Datei der Begriff root vorkommt. Wenn ja, wird eine entsprechende Erfolgsmeldung ausgegeben.

10.4 73 Es ist also problemlos möglich, Anweisungen in Shellskripten ineinander zu verschachteln. Sie können übrigens auch Schleifen wieder in Schleifen verschachteln, aber das erspare ich Ihnen vorerst. Eine weitere Möglichkeit, Listen dynamisch zu erzeugen, sind die Shellexpansionen, die Sie in Lektion 5»Shell-Expansion und Strings«kennengelernt haben. 1 #!/bin/bash 3 for zahl in {1..10} 4 do 5 echo $zahl 6 done Codebeispiel 10.8 for3.sh oliver@frodo:~$ bash for3.sh 1 3 4 5 6 7 8 9 10 10.4 Schleifen erlauben es Ihnen, denselben Codeblock mehrfach auszuführen, ohne ihn mehrfach hinschreiben zu müssen. Sie sind ein unverzichtbares Hilfsmittel, um Shellskripte kurz und übersichtlich zu halten. In dieser Lektion haben Sie die beiden Schleifen while und for kennengelernt und einige Anwendungen ausprobiert. Testen Sie Ihr Wissen 1. Wie lange wird eine while -Schleife ausgeführt?. Wie sorgen Sie dafür, dass die Bedingung einer while -Schleife irgendwann unwahr wird? 3. Wie oft wird eine for -Schleife ausgeführt? 4. Wodurch werden die Elemente der Liste getrennt? Wie können Sie das Verhalten verändern? 5. Wie können Sie die Ausgabe eines Kommandos als Liste für eine for -Schleife verwenden?