|
|
| (74 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) |
| Zeile 1: |
Zeile 1: |
| =Bash Basics= | | =Allgemeines= |
| *[[Einfache Shellsonderzeichen]] | | *[[Thomas Will]] |
| *[[Bash Eingabe/Ausgabe]] | | *[[Zeiten I.]] |
| *[[Jokerzeichen]] | | =Themen= |
| *[[Prinzip der Bash]] | | *[[Bash Programmierung Inhalt]] |
| *[[Interpretator]] | | <!-- == Tag 1 == --> |
| *[[Ablauf eines Shell-Skriptes]] | | * [[Die Geschichte der Shells]] |
| *[[Möglichkeiten ein Shellskript aufzurufen]] | | * [[Ziele des IT Trainings Bash Programmierung]] |
| *[[Bash Variablen]] | | * [[Arten von Shells]] |
| *[[Bash Dateien]] | | * [[Prinzip der Bash]] |
| *[[Here Dokument]] | | * [[Unterschiede zwischen bash und powershell]] |
| | * [[Skript Interpreten in Linux]] |
| | * [[Möglichkeiten ein Shellskript aufzurufen]] |
| | * [[Bash Eingabe, Ausgabe und Pipes]] |
| | * [[Einfache Shellsonderzeichen]] |
| | * [[Jokerzeichen/Wildcard]] |
| | * [[Ein paar Kommandos]] |
| | * [[Kommandolokalisierung]] |
| | * [[Bash ssh in Programmen nutzen]] |
| | <!-- == Tag 2 == --> |
| | * [[Ablauf eines Shell-Skriptes]] |
| | * [[Bash Variablen]] |
| | * [[Bash Dateien]] |
| | * [[Here Dokument]] |
| | * [[Here String]] |
| | * [[read-Kommando]] |
| | * [[Endestatus]] |
| | * [[Bash Einfache Verzweigungen]] |
| | * [[test-Kommando]] |
| | * [[Bash Das neue Test Kommando]] |
| | * [[Rechnen mit der Bash]] |
| | <!-- == Tag 3 == --> |
| | <!-- == Tag 4 == --> |
| | * [[Bash Der if-Block]] |
| | * [[Bash Der case-Block]] |
| | * [[Bash Die while-Schleife]] |
| | * [[Bash Die until-Schleife]] |
| | * [[Bash Die for-Schleife]] |
| | * [[Bash Steuerung der Ablaufanweisungen]] |
| | * [[Bash funktion]] |
| | * [[cron]] |
| | * [[Bash Signalverarbeitung]] |
| | <!-- == Tag 5 == --> |
| | * [[Bash printf]] |
| | * [[Aliase]] |
| | * [[Prozesse]] |
| | * [[Bash Filedeskriptoren]] |
| | * [[Bash Farben]] |
| | * [[Bash getopts]] |
| | * [[Bash eval]] |
| | * [[Optionen der Bash]] |
| | * [[Bit Operationen mit der Bash]] |
| | * [[Bash Skripte]] |
| | * [[Mail Kommando]] |
| | * [[Bash Passwort generieren]] |
| | * [[Bash Alter eine Datei]] |
| | * [[Ssh VPN]] |
| | * [[Aufgaben gesamt]] |
|
| |
|
| =read-Kommando=
| | = Links= |
| Mit read wird eine Eingabezeile eingelesen und deren Inhalt Variablen zugewiesen. Die Eingabe wird anhand der
| | * http://openbook.rheinwerk-verlag.de/shell_programmierung/ |
| Trennzeichen in einzelne Token zerlegt und der Reihe nach den Variablen zugewiesen. Stehen mehr Token zur
| | * http://mywiki.wooledge.org/BashFAQ/031 |
| Verfügung als Variablen, so wird die letzte Variable mit allen noch nicht zugewiesenen Token belegt; stehen weniger
| | * http://tldp.org/LDP/abs/html/index.html |
| Token bereit, bleibt der Inhalt der überschüssigen Variablen leer:
| | * http://openbook.rheinwerk-verlag.de/shell_programmierung/shell_006_003.htm |
| <syntaxhighlight lang="bash">
| | * https://kuepper.userweb.mwn.de/informatik/printf.pdf |
| #!/bin/bash
| |
| echo "wie heißen sie?"
| |
| read NAME VORNAME
| |
| echo "Sie heißen $VORNAME $NAME"
| |
| </syntaxhighlight>
| |
| read wird in dieser Form sehr selten benutzt da der automatische Charakter von shell Skripten dadurch verloren geht.
| |
| | |
| =Einfache Verzweigungen=
| |
| In Abhängigkeit vom Returncode eines Befehls oder einer Pipe kann mit den Sonderzeichen ''&&'' und ''||'' eine
| |
| Verzweigung durchgeführt werden.
| |
| *echo ''das ist sux1.'' > sux1
| |
| *rm sux1 && echo ''sux1 ist geloescht!''
| |
| *rm sux1 || echo ''sux1 konnte nicht geloescht werden.''
| |
| Der Befehl nach ''&&'' wird dabei nur ausgeführt, wenn der Returncode des vorherigen Befehls oder der vorherigen
| |
| Pipe 0 war, also der Befehl vor der Pipe fehlerfrei ausgeführt wurde. Ist ein Befehl vor einer Pipe nicht erfolgreich
| |
| (Returncode != 0), wird der Befehl nach ''||'' ausgeführt.
| |
| | |
| =Endestatus=
| |
| N:ach der Ausführung eines Befehls wird ein Returncode (Endestatus) zurückgeliefert. Mit Hilfe des Returncodes lässt
| |
| sich feststellen, ob der letzte Befehl fehlerfrei ausgeführt wurde.
| |
| Returncode = 0 Letzter Befehl wurde fehlerfrei ausgeführt.
| |
| Returncode ≠ 0 Letzter Befehl wurde nicht fehlerfrei ausgeführt.
| |
| Das Kommando ''true'' liefert den Returncode 0, ''false'' liefert den Returncode ≠ 0 .
| |
| Bei einigen Befehlen wird die zurückgelieferte Fehlermeldung (Returncode ≠ 0) noch weiter differenziert (siehe man
| |
| fsck). In der Systemvariablen $? ist der aktuelle Returncode abgelegt und kann vom Benutzer abgefragt werden.
| |
| Bsp.:
| |
| *fsck asasas
| |
| *echo $?
| |
| 16
| |
| oder
| |
| *ping www.xinux.de -w 1 -c 1 > /dev/null 2>&1
| |
| *ping 172.20.103.2 -w 1 -c 1 > /dev/null 2>&1
| |
| *echo $?
| |
| 0
| |
| Erkenntnis: Rechner ist erreichbar
| |
| | |
| *ping 172.20.103.99 -w 1 -c 1 > /dev/null 2>&1
| |
| *echo $?
| |
| 1
| |
| Erkenntnis: Rechner ist nicht erreichbar
| |
| | |
| *touch bohnen
| |
| *rm bohnen 2> /dev/null
| |
| *echo $?
| |
| 0
| |
| Erkenntnis: Löschen war erfolgreich
| |
| | |
| *rm bohnen 2> /dev/null
| |
| *echo $?
| |
| 1
| |
| Erkenntnis: Löschen war nicht erfolgreich
| |
| | |
| =test-Kommando=
| |
| Der eingebaute Befehl ''test'' gibt sein Ergebnis als Returncode zurück. Dieser Befehl wird daher oft in
| |
| Kontrollstrukturen der bash zur Verzweigung verwendet.
| |
| | |
| Es existieren 2 Schreibweisen:
| |
| | |
| '''test''' bedingung
| |
| '''[''' bedingung ''']'''
| |
| | |
| Ist das von ''bedingung'' zurückgelieferte Ergebnis wahr, wird der Returncode 0 übergeben, sonst ungleich 0.
| |
| ''bedingung'' kann ein numerischer Vergleich, ein Stringvergleich, eine Prüfung von Objekteigenschaften oder
| |
| eine beliebige Kombination der vorhergehenden sein.
| |
| | |
| ==Numerischer Vergleich==
| |
| '''test''' zahl1 '''-op''' zahl2 (op: eq, ne, lt, gt, ge, le)
| |
| *ZAHL=4
| |
| *test $ZAHL -eq "4" && echo stimmt
| |
| | |
| | |
| {| border=1 cellpadding="2"
| |
| | -eq
| |
| | gleich
| |
| |-
| |
| | -ne
| |
| | ungleich
| |
| |-
| |
| | -lt
| |
| | kleiner
| |
| |-
| |
| | -gt
| |
| | größer
| |
| |-
| |
| | -ge
| |
| | größer oder gleich
| |
| |-
| |
| | -le
| |
| | kleiner oder gleich
| |
| |}
| |
| | |
| ==Stringvergleich==
| |
| '''test''' string1 '''=''' string2
| |
| '''test''' string1 '''!=''' string2
| |
| '''test''' –n string oder test string (Länge von string größer null)
| |
| '''test''' –z string (Länge von string gleich null)
| |
| | |
| *HOBBIT=frodo
| |
| *'''test''' $HOBBIT '''=''' "bilbo" && echo frodo
| |
| *'''test''' $HOBBIT '''=''' "bilbo" && echo bilbo
| |
| *HOBBIT=bilbo
| |
| *'''test''' $HOBBIT '''=''' "bilbo" && echo bilbo
| |
| bilbo
| |
| | |
| ==Objekteigenschaften==
| |
| '''test -op''' objekt
| |
| {| border=1 cellpadding="2"
| |
| | d || Directory
| |
| |-
| |
| | f || Datei
| |
| |-
| |
| | s || nicht leere Datei
| |
| |-
| |
| | r || leserecht auf das Objekt
| |
| |-
| |
| | w || schreibrecht auf das Objekt
| |
| |-
| |
| | x || ausführungsrecht auf das Objekt
| |
| |}
| |
|
| |
| *test -f /etc/shadow && echo sicheres system
| |
| sicheres system
| |
| *test -r /etc/shadow || echo so ist es richtig
| |
| so ist es richtig
| |
| | |
| ==Prioritäten bei logischen Verknüpfungen==
| |
| {| border=1
| |
| | runde Klammer || Negation || AND || OR
| |
| |-
| |
| | '''()''' || '''!''' || '''-a''' || '''-o'''
| |
| |}
| |
| | |
| | |
| test \'''(''' -r dat '''-o''' -w dat \''')'''
| |
| test '''!''' \'''(''' -r dat '''-o''' -w dat \''')'''
| |
| test ''$name'';echo $?
| |
| | |
| *! test -r /etc/shadow && echo so ist es richtig
| |
| so ist es richtig
| |
| =Optionen der Shell=
| |
| Die Shell hat verschiedene sehr nützliche Optionen.
| |
| | |
| =Man kann sie sich mit Optionen den aktuellen Shell anzeigen lassen=
| |
| *echo $-
| |
| himBHs
| |
| =Mit dem set kann man die Optionen setzen oder deaktivieren=
| |
| *set -|+optionen...
| |
| =Wichtige Optionen der Bash=
| |
| {| class="wikitable"
| |
| |+Optionen der Shell
| |
| |-
| |
| |f
| |
| |Dateinamen expandieren ausschalten
| |
| |-
| |
| |n
| |
| |Kommandos nur lesen und nicht ausführen
| |
| |-
| |
| |x
| |
| |Jedes einfache Kommando unmittelbar vor der Ausführung ausgeben. Ersetzungen werden vorgenommen
| |
| |-
| |
| |a
| |
| |Alle angelegten Variablen für den Export markieren
| |
| |-
| |
| |e
| |
| |Shell verlassen wenn ein Kommando nicht erfolgreich ausgeführt werden kann.
| |
| |-
| |
| |v
| |
| |Jede Zeile wird ausgegeben bevor sie ausgeführt wird
| |
| |-
| |
| | -
| |
| |So kann Positionsparameter setzen die mit einem - beginnen
| |
| |}
| |
| | |
| =Der if-Block=
| |
| '''if''' programm
| |
| '''then'''
| |
| anweisung1
| |
| '''else'''
| |
| anweisung2
| |
| '''fi'''
| |
| Der if-Block verzweigt in Abhängigkeit des Returncodes des Programmes das ausgeführt wird. Ist der
| |
| Returncode gleich null, wird Anweisung1 ausgeführt; ist der Returncode ungleich null, wird Anweisung2
| |
| ausgeführt.
| |
| | |
| [[Image:if.jpg]]
| |
| | |
| Der else-Zweig kann ausgelassen oder durch einen elif-Zweig ersetzt werden. Der elif-Zweig ist eine
| |
| Besonderheit bei Verschachtelungen.
| |
| *cat rechnertest
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| if ping -c 1 -w 1 $1 > /dev/null 2>&1
| |
| then
| |
| echo "rechner lebt"
| |
| else
| |
| echo "rechner ist tot"
| |
| fi
| |
| </syntaxhighlight>
| |
| *./rechnertest 172.20.103.1
| |
| rechner lebt
| |
| *./rechnertest 172.20.103.99
| |
| rechner ist tot
| |
| | |
| ==Variante ohne else==
| |
| *cat rechnertest.spar
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| if ping -c 1 -w 1 $1 > /dev/null 2>&1
| |
| then
| |
| echo "rechner lebt"
| |
| fi
| |
| </syntaxhighlight>
| |
| | |
| *./rechnertest.spar 172.20.103.1
| |
| rechner lebt
| |
| *./rechnertest.spar 172.20.103.99
| |
| | |
| ==Sonderform mit elif==
| |
| *cat el
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| echo -n "wie heissen Sie :"
| |
| read NAME
| |
| if test $NAME = "thomas"
| |
| then
| |
| echo "hallo meister"
| |
| elif test $NAME = "martin"
| |
| then
| |
| echo "hallo vizemeister"
| |
| else
| |
| echo "hallo wurm"
| |
| fi
| |
| </syntaxhighlight>
| |
| *./el
| |
| wie heissen Sie :thomas
| |
| hallo meister
| |
| *./el
| |
| wie heissen Sie :martin
| |
| hallo vizemeister
| |
| *./el
| |
| wie heissen Sie :suxer
| |
| hallo wurm
| |
| | |
| =Der case-Block=
| |
| Der case-Block dient der Durchführung eines Stringvergleiches. Er wird sequentiell von oben nach unten abgearbeitet. Bei
| |
| Übereinstimmungen mit einem definierten Muster wird der darauf folgende Befehl ausgeführt (bzw. die darauf folgende
| |
| Befehlsliste). Bei der ersten gefundenen Übereinstimmung terminiert der case-Block.
| |
| | |
| Bei der Definition des Musters können die Sonderzeichen der bash zur Dateinamengenerierung verwendet werden. Zusätzlich
| |
| kann ''|'' für eine logische OR-Verknüpfung benutzt werden.
| |
| | |
| *cat case1
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| case $1 in
| |
| rock|rocknroll)
| |
| echo "stones sind gut"
| |
| ;;
| |
| schlager)
| |
| echo "guildo ist ein gott"
| |
| ;;
| |
| volks)
| |
| echo "was an der waffel?"
| |
| ;;
| |
| *)
| |
| echo "kein bock auf musik"
| |
| ;;
| |
| esac
| |
| </syntaxhighlight>
| |
| *./case1 rock
| |
| stones sind gut
| |
| *./case1 rocknroll
| |
| stones sind gut
| |
| *./case1 schlager
| |
| guildo ist der meister
| |
| *./case1 volks
| |
| was an der waffel?
| |
| *./case1 kllkjl
| |
| kein bock auf musik
| |
| | |
| =Rechnen mit der Bash=
| |
| ; '''$(())'''
| |
| ; '''expr'''
| |
| ; '''bc'''
| |
| ==Arithmetische Substitution==
| |
| Die $(()) oder $[ ] ist die arithmetische Erweiterungsmethode der Bash.
| |
| *echo $((7+5))
| |
| 12
| |
| *echo $((7*5))
| |
| 35
| |
| *echo $((7/5))
| |
| 1
| |
| *echo $((7-5))
| |
| 2
| |
| *echo $((7%5))
| |
| 2
| |
| *ZAHL=5 ; ZAHL=$(($ZAHL + 1)) ; echo $ZAHL
| |
| 6
| |
| ==Der expr-Befehl==
| |
| Erlaubt die Durchführung komplexer Stringoperationen und Ganzzahlarithmetik.
| |
| *expr 7 + 5
| |
| 12
| |
| *expr 7 \* 5
| |
| 35
| |
| *expr 7 / 5
| |
| 1
| |
| *expr 7 – 5
| |
| 2
| |
| *expr 7 % 5
| |
| 2
| |
| *ZAHL=5 ; ZAHL=$(expr $ZAHL + 1) ; echo $ZAHL
| |
| 6
| |
| ==bc - interaktiver Taschenrechner==
| |
| *bc
| |
| bc 1.06
| |
| Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
| |
| This is free software with ABSOLUTELY NO WARRANTY.
| |
| For details type `warranty'.
| |
| 12 * 3
| |
| 36
| |
| quit
| |
| | |
| Mit der Option -l wird die mathematische Bibliothek eingeschaltet
| |
| | |
| *bc -l
| |
| bc 1.06
| |
| Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
| |
| This is free software with ABSOLUTELY NO WARRANTY.
| |
| For details type `warranty'.
| |
| 7 / 5
| |
| 1.40000000000000000000
| |
| quit
| |
| | |
| Da bc auch von STDIN lesen kann, kann man es auch in Shellskripten benutzen.
| |
| | |
| *echo 7/5 | bc -l
| |
| 1.40000000000000000000
| |
| | |
| *ZAHL=5 ; ZAHL=$(echo $ZAHL+1 | bc -l) ; echo $ZAHL
| |
| 6
| |
| | |
| =Die while-Schleife=
| |
| ==Einfache Form==
| |
| Die while-Schleife wird so lange durchlaufen, bis der Returncode ungleich null ist.
| |
| *cat proggi
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| while [ $# -ge 1 ]
| |
| do
| |
| echo $1
| |
| echo $#
| |
| shift
| |
| done
| |
| </syntaxhighlight>
| |
| | |
| *./proggi blau gelb gruen
| |
| blau
| |
| 3
| |
| gelb
| |
| 2
| |
| gruen
| |
| 1
| |
| | |
| Darstellung als Struktogramm nach Nassi / Shneiderman:
| |
| | |
| [[Image:while.jpg]]
| |
| | |
| Beispiel:
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| COUNTER=$1
| |
| while [ $COUNTER -ge 1 ]
| |
| do
| |
| echo $COUNTER
| |
| COUNTER=$(($COUNTER-1))
| |
| done
| |
| echo "BUMM BUMM"
| |
| </syntaxhighlight>
| |
| *./countdown 5
| |
| 5
| |
| 4
| |
| 3
| |
| 2
| |
| 1
| |
| BUMM BUMM
| |
| | |
| ==Sonderform von while==
| |
| Die Variable SUX wird nacheinander mit jeder Zeile der Datei
| |
| /etc/passwd belegt, bis die letzte Zeile der Datei /etc/passwd erreicht ist.
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| while read SUX
| |
| do
| |
| echo $SUX
| |
| done < /etc/passwd
| |
| </syntaxhighlight>
| |
| Selbstgebautes cat
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| while read ZEILE
| |
| do
| |
| echo $ZEILE
| |
| done < $1
| |
| </syntaxhighlight>
| |
| Selbstgebautes tac
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| COUNT=0
| |
| while read ZEILE
| |
| do
| |
| FELD[$COUNT]=$ZEILE
| |
| COUNT=$(($COUNT+1))
| |
| done < $1
| |
| while [ $COUNT -ge 0 ]
| |
| do
| |
| echo ${FELD[$COUNT]}
| |
| COUNT=$(($COUNT-1))
| |
| done
| |
| </syntaxhighlight>
| |
| =Die until-Schleife=
| |
| | |
| Die until-Schleife wird so lange durchlaufen, bis der Returncode der Abbruchbedingung gleich null ist.
| |
| | |
| '''until''' test ''$# -eq 0
| |
| '''do'''
| |
| echo $1
| |
| shift
| |
| '''done'''
| |
| | |
| Darstellung als Struktogramm nach Nassi / Shneiderman:
| |
| | |
| [[Image:until.jpg]]
| |
| | |
| = Die for-Schleife =
| |
| ==Standard For Schleife==
| |
| Bei der for-Schleife wird bei jedem Durchlauf der Schleifenvariablen ein Wert aus einer angegebenen Liste
| |
| zugewiesen; die Liste wird dabei von links nach rechts durchlaufen. Nach der letzten Wertzuweisung terminiert die
| |
| for-Schleife.
| |
| | |
| *cat fussball
| |
| <syntaxhighlight lang="bash">
| |
| #!/bin/bash
| |
| for CLUB in fck bvb schalke bmg
| |
| do
| |
| echo $CLUB
| |
| done
| |
| </syntaxhighlight>
| |
| *./fussball
| |
| fck
| |
| bvb
| |
| schalke
| |
| bmg
| |
| | |
| Darstellung als Struktogramm nach Nassi / Shneiderman:
| |
| | |
| [[Image:for.jpg]]
| |
| | |
| ==For Schleife mit Stellungsparametern==
| |
| Wird keine Liste angegeben, wird standardmäßig die Liste der Stellungsoperanden benutzt. Folgende Anweisungen sind äquivalent
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| for LAUF in $*
| |
| do
| |
| echo $LAUF
| |
| done
| |
| </syntaxhighlight>
| |
| Kurzform :
| |
| <syntaxhighlight>
| |
| for LAUF
| |
| do
| |
| echo $LAUF
| |
| done
| |
| </syntaxhighlight>
| |
| | |
| ==For Schleife mit Dateien aus dem aktuellen Verzeichnis==
| |
| Der Stern würde durch alle Dateien des aktuellen Verzeichnisses ersetzt werden.
| |
| Daraus folgt, dass der Name jeder Datei nacheinander in die Variable LAUF geschreiben wird. Die Anzahl der Schleifenläufe
| |
| ist identisch mit der Anzahl von Dateien.
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| for LAUF in *
| |
| do
| |
| echo $LAUF
| |
| done
| |
| </syntaxhighlight>
| |
| Hier die Variante mit einem grossen K
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| for LAUF in K*
| |
| do
| |
| echo $LAUF
| |
| done
| |
| </syntaxhighlight>
| |
| ==For Schleife im C Stil==
| |
| Mit Bash-Version 2.0.4 wurde die for-Schleife um eine an die Programmier-sprache C angelehnte Syntaxvariante erweitert:
| |
| | |
| for ((Initialisierung der Laufvaribale; Laufbedingung; Veränderung der Laufvariable))
| |
| do
| |
| Kommando
| |
| done
| |
| *cat foor
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| for ((I=1;I<5;I++))
| |
| do
| |
| echo $I
| |
| done
| |
| </syntaxhighlight>
| |
| *./foor
| |
| 1
| |
| 2
| |
| 3
| |
| 4
| |
| | |
| =Steuerung der Ablaufanweisungen=
| |
| ==exit n==
| |
| Der aktuelle Prozess und damit auch die bash werden abgebrochen. Für n kann eine Zahl zwischen 0 und 255 angegeben werden;
| |
| damit kann der Returncode des Prozesses festgelegt werden, der an den aufrufenden Prozess übergeben wird.
| |
| | |
| Zur Schleifensteuerung können die Befehle ''continue'' und ''break'' verwendet werden. Sie dürfen nur zwischen den
| |
| Schlüsselwörtern ''do'' und ''done'' stehen.
| |
| | |
| ==continue n==
| |
| Der aktuelle Schleifendurchlauf wird abgebrochen, um mit dem nächsten Durchlauf zu beginnen. Bei Verschachtelungen kann
| |
| durch Angabe einer Ganzzahl in der n-ten Schleifenebene angesetzt werden.
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| for CLUB in fck bvb bayern fcs
| |
| do
| |
| if [ $CLUB = "bayern" ]
| |
| then
| |
| echo "zeig ich nicht an"
| |
| continue
| |
| exit
| |
| fi
| |
| echo $CLUB
| |
| done
| |
| </syntaxhighlight>
| |
| *./fussball
| |
| fck
| |
| bvb
| |
| zeig ich nicht an
| |
| fcs
| |
| | |
| =Select=
| |
| Mit dem Befehl bash select können verschiedene Arten von Menüerstellungsaufgaben, das Erstellen einer menübasierten Listen, das Erstellen eines Menüs aus Dateiinhalten usw. ausgeführt werden.
| |
| | |
| | |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| select auswahl in Punkt1 Punkt2 Punkt3 Punkt4
| |
| do
| |
| echo "Ihre Auswahl war : $auswahl"
| |
| done
| |
| </syntaxhighlight>
| |
| | |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| PS3="Datei zum Editieren auswählen : "
| |
| select AUSWAHL in *.sh exit
| |
| do
| |
| case "$AUSWAHL" in
| |
| exit)
| |
| echo "exit"
| |
| break
| |
| ;;
| |
| "")
| |
| echo "$REPLY: Ungültige Auswahl"
| |
| ;;
| |
| *)
| |
| if [ -d "$AUSWAHL" ]
| |
| then
| |
| echo "Verzeichnis kann nicht editiert werden"
| |
| continue
| |
| else
| |
| $EDITOR $AUSWAHL
| |
| fi
| |
| break
| |
| ;;
| |
| esac
| |
| done
| |
| </syntaxhighlight>
| |
| | |
| | |
| | |
| | |
| ==break n==
| |
| Die aktuelle Schleife wird abgebrochen, danach wird mit der ersten Anweisung nach der Schleife weitergemacht. Bei
| |
| Verschachtelungen wird auf der n-ten Schleifenebene aufgesetzt.
| |
| | |
| Anmerkung:
| |
| Ein sinnvoller Einsatz dieser Konstrukte liegt in der Behandlung von Ausnahmen (Fehler). Intensiver Einsatz macht die
| |
| Programme unleserlich und schwer kontrollierbar. Daher ist eine sparsame Verwendung empfehlenswert.
| |
| | |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| while true
| |
| do
| |
| test -f /tmp/sux && break
| |
| echo "unn weiter"
| |
| sleep 3
| |
| done
| |
| echo "und tschuess"
| |
| </syntaxhighlight>
| |
| | |
| =Funktionen=
| |
| [[bash funktion]]
| |
| | |
| =Signalbehandlung=
| |
| ==Signale bei der Programmierung der bash==
| |
| Es existieren verschiedene Möglichkeiten, auf welchem Wege Signale gesendet werden können:
| |
| | |
| # von aussen:
| |
| ## Benutzer (< DEL >, < CTRL >|, etc.)
| |
| ## Prozesse (kill, alarm)
| |
| # von innen:
| |
| ## Programmfehler (Adressfehler, ungültiger Befehl, Division durch 0, etc.)
| |
| | |
| Signale dienen der Interprozesskommunikation. Diese Nachrichten beschränken sich allerdings auf die Übertragung eines einzigen Wertes.
| |
|
| |
| Von den Befehlen ''trap'' und ''kill'' werden folgende Signale verwendet:
| |
| | |
| {| border="1" cellpadding="2"
| |
| ! Signalnummer
| |
| ! Bedeutung
| |
| |-
| |
| | 0
| |
| | Beenden von bash
| |
| |-
| |
| | SIGHUP 1
| |
| | Logoff von einer Datensichtstation
| |
| |-
| |
| | SIGINT 2
| |
| | Drücken der Taste < DEL >
| |
| |-
| |
| | SIGQUIT 3
| |
| | Drücken der Taste < CTRL > + c
| |
| |-
| |
| | SIGKILL 9
| |
| | kill: unbedingter Prozessabbruch
| |
| |-
| |
| | SIGTERM 15
| |
| | Programmbeendigung
| |
| |}
| |
| | |
| ==Reaktion eines Prozesses auf den Empfang eines Signals==
| |
| * Der Prozess beendet sich (meist Standardeinstellung).
| |
| * Der Prozess ignoriert das Signal. (Ausnahme: SIGKILL)
| |
| * Der Prozess fängt das Signal ab, d.h. er leitet eine selbst definierte Reaktion ein.
| |
| | |
| =Der Befehl trap =
| |
| '''Funktionen:'''
| |
| | |
| ;Signalbehandlung setzen
| |
| (Nach Beendigung der bash werden die betreffenden temporären Dateien gelöscht)
| |
| *trap 'rm *.tmp' 0
| |
| *trap 'who; exit 1' 2 3
| |
|
| |
| ;Liefern von Informationen über gesetzte Signalbehandlung
| |
| *trap
| |
| | |
| ;Zurücksetzen der Signalbehandlung
| |
| *trap 2 3
| |
| | |
| ;Import von Signalen
| |
| *trap : 2 3
| |
| *trap '' 2 3
| |
| | |
| ;Demonstriert die Funktion trap zum Abfangen von Signalen
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| trap 'echo trap ausgelöst' 2
| |
| i=0
| |
| while [ $i -lt 5 ]
| |
| do
| |
| echo "Bitte nicht stören!"
| |
| sleep 2
| |
| i=`expr $i + 1`
| |
| done
| |
| </syntaxhighlight>
| |
| Bemerkung: Die Signalbehandlung selbst wird nicht an Kindprozesse weitervererbt. Das Ignorieren von Signalen hingegen wird weitervererbt.
| |
| | |
| =Weitere Möglichkeiten der Bash-Shell=
| |
| ==Alias-Namen==
| |
| *[[aliase]]
| |
| | |
| =Filedeskriptoren=
| |
| ==Schreibenden Deskriptor==
| |
| ;anlegen
| |
| *exec 5> /tmp/five
| |
| ;rein schreiben
| |
| *echo eins >&5
| |
| *echo zwei >&5
| |
| *echo drei >&5
| |
| ;ausgeben
| |
| *cat /tmp/five
| |
| ;aufheben
| |
| *exec 5>&-
| |
| ;führt zu Fehler
| |
| *echo vier >&5
| |
| ==Lesender Deskriptor==
| |
| ;anlegen
| |
| *exec 7< /etc/hosts
| |
| ;auslesen
| |
| *cat <&7
| |
| ;geht nur einmal
| |
| *cat <&7
| |
| | |
| ==Gleichzeitiges Lesen aus verschiedenen Dateien==
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| exec 3< /etc/passwd
| |
| exec 4< /etc/shadow
| |
| while true
| |
| do
| |
| read var3 <&3
| |
| read var4 <&4
| |
| echo passwd $var3
| |
| echo shadow $var4 ;
| |
| test -z $var4 && break
| |
| done
| |
| </syntaxhighlight>
| |
| ==Gleichzeitiges Lesen aus Datei und Standardeingabe==
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| exec 3< $1
| |
| while read line <&3
| |
| do
| |
| echo $line
| |
| printf "Eine weitere Zeile einlesen? [j/n] : "
| |
| read REPLY
| |
| test "$REPLY" = "n" && break
| |
| done
| |
| </syntaxhighlight>
| |
| | |
| =Bearbeiten von Farben=
| |
| | |
| Um die Farben in der Shell zu ändern, müssen wir bestimmte Zeichenfolgen senden. Die Zeichenkette \033\13301;31m würde z.B. alles Weitere in Rot ausgeben.
| |
| | |
| Format: \033\133;m
| |
| | |
| Diese Methode kann allerdings beim Setzen der Variable $PS1, die den Prompt kontrolliert, dazu führen, dass der Zeilenumbruch falsch berechnet wird. Deshalb ist in diesem Fall der Einschluss in \[ \] erforderlich.
| |
| | |
| Format: \[\033\133;m\]
| |
| | |
| Um mit dem Farbigen aufzuhören und wieder normal zu schreiben sendet man einfach folgende Zeichenfolge:
| |
| | |
| \033\1330m
| |
| | |
| Textdekorationen:
| |
| 00 - Schmaldruck
| |
| 01 - Keine
| |
| 02 - dunkle Version der Farbe
| |
| 04 - Unterstreichen
| |
| 05 - Invertieren
| |
| | |
| Farben:
| |
| 30 - Schwarz
| |
| 31 - Rot
| |
| 32 - Grün
| |
| 33 - Gelb
| |
| 34 - Blau
| |
| 35 - Lila
| |
| 36 - Cyan
| |
| 37 - Grau
| |
| | |
| Hintergründe färben:
| |
| 40 - Schwarz
| |
| 41 - Rot
| |
| 42 - Grün
| |
| 43 - Gelb
| |
| 44 - Blau
| |
| 45 - Lila
| |
| 46 - Cyan
| |
| 47 - Grau
| |
| | |
| Austesten wie es dann genau aussieht kann man das mit den folgenden Befehlen:
| |
| | |
| for i in `seq 40 47`;do echo -e "Farbnummer:\033\13301;"$i"m $i \033\01330m";done
| |
| for i in `seq 30 37`;do echo -e "Farbnummer:\033\13301;"$i"m $i \033\01330m";done
| |
| | |
| =getopts=
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| function examine()
| |
| {
| |
| FILE=$1
| |
| shift
| |
| echo "Rights on $FILE"
| |
| for k in $*
| |
| do
| |
| case $k in
| |
| u) echo USER : $(ls -l $FILE | cut -c 1-3) ;;
| |
| g) echo GROUP: $(ls -l $FILE | cut -c 4-6) ;;
| |
| o) echo OTHER: $(ls -l $FILE | cut -c 7-9) ;;
| |
| esac
| |
| done
| |
| }
| |
| while getopts ugof: opt
| |
| do
| |
| case $opt in
| |
| u) OPT="${OPT} u";;
| |
| g) OPT="${OPT} g";;
| |
| o) OPT="${OPT} o";;
| |
| f) DAT=$OPTARG;;
| |
| ?) echo "USAGE: $0 -ugo -f FILE"; exit 2 ;;
| |
| esac
| |
| done
| |
| examine $DAT $OPT
| |
| </syntaxhighlight>
| |
| ;Erklärung
| |
| *Das Program kann mit den Optionen -u -g -o und -f Datei aufgerufen werden.
| |
| *Die Optionen ugo werden in der Variable $OPT "gesammelt".
| |
| *Alle Optionen werden an die Funktion examine übergeben.
| |
| *Die Optionen werden oben getrennt und je nach vorhandener Option werden Anweisungen ausgeführt.
| |
| | |
| | |
| *http://openbook.galileocomputing.de/shell_programmierung/shell_005_007.htm
| |
| | |
| =printf=
| |
| Formatierte Ausgabe mit printf
| |
| | |
| Im einfachsten Fall wird ein fester Text auf dem Bildschirm ausgegeben:
| |
| *printf("Dies ist ein einfaches Beispiel");
| |
| Der Text kann auch Sonderzeichen (z. B. Zeilenumbrüche) enthalten:
| |
| *printf("Hier werden \n zwei Zeilen ausgegeben!");
| |
| Die Zeichensequenz \n bewirkt einen Sprung an den Anfang der folgenden Bildschirmzeile. Weitere gebräuchliche Sonderzeichen sind:
| |
| {| class="wikitable"
| |
| |-
| |
| |\n
| |
| |Sprung an den Anfang der folgenden Bildschirmzeile
| |
| |-
| |
| |\b
| |
| |Gehe ein Zeichen zurück
| |
| |-
| |
| |\a
| |
| |Akustisches Signal
| |
| |-
| |
| |\r
| |
| |Sprung an den Anfang der aktuellen Bildschirmzeile
| |
| |-
| |
| |\\
| |
| |Ausgabe des Gegenschrägstrichs "\" (Backslash)
| |
| |-
| |
| |%%
| |
| |Ausgabe des Prozent-Zeichens "%"
| |
| |-
| |
| |\"
| |
| |Ausgabe eines doppelten Anführungszeichens
| |
| |-
| |
| |\t
| |
| |Sprung zur nächsten Tabulatorposition
| |
| |}
| |
| Sollen aktuelle Variablenwerte ausgegeben werden, werden in den Aufruf der
| |
| | |
| Funktion printf entsprechende „Platzhalter“ eingefügt:
| |
| *int x = 10;
| |
| *printf("Der Wert %d wurde der Variablen x zugewiesen.", x);
| |
| Auf dem Bildschirm erfolgt die Ausgabe „Der Wert 10 wurde der Variablen x zugewiesen“, es wird also der Platzhalter %d durch den aktuellen Wert der Variablen x
| |
| ersetzt. Es ist möglich, mehrere Variablen zugleich auszugeben:
| |
| *int x = 123, y = 234;
| |
| *printf("x = %d und y = %d", x, y);
| |
| Die Ausgabe lautet in diesem Fall „x = 123 und y = 234“. Für jede Variable ist ein
| |
| eigener Platzhalter (hier: %d) notwendig. Die auszugebenden Variablen werden
| |
| durch Kommas getrennt aufgelistet. Für jeden Platzhalter muss dabei eine Variable angegeben werden (hier: x, y).
| |
| Es ist zu beachten, dass der Platzhalter zum Typ der auszugebenden Variablen
| |
| passt (z. B. dient %d zur Ausgabe einer Variablen des Typs int, short oder long).
| |
| Weitere Platzhalter sind:
| |
| | |
| {| class="wikitable"
| |
| |-
| |
| |%d, %i
| |
| |int, short, long
| |
| |Ganze Zahl
| |
| |-
| |
| |%x, %X
| |
| |int, short, long
| |
| |Ganze Zahl, Ausgabe als Hexadezimalzahl
| |
| |-
| |
| |%f
| |
| |float, double
| |
| |Fließkommazahl
| |
| |-
| |
| |%e, %E
| |
| |float, double
| |
| |Fließkommazahl, Ausgabe im Exponentialformat
| |
| |-
| |
| |%c
| |
| |char
| |
| |Einzelnes Zeichen (Buchstabe, Ziffer, …)
| |
| |-
| |
| |%s
| |
| |char*
| |
| |Zeichenkette („String“)
| |
| |}
| |
| ;Beispiel:
| |
| *int i = 10; double d = 22.22; char c = 'X';
| |
| *char* str = "abcdefg...";
| |
| *printf("Beispiel zu printf:\n");
| |
| *printf("%d, %f, %c\n", i, d, c);
| |
| *printf("%s", str);
| |
| Es kann die Breite des Ausgabebereichs angegeben werden. So wird mit %10d
| |
| eine ganze Zahl rechtsbündig in einem Bereich von 10 Zeichen Länge ausgegeben:
| |
| int i = 123;
| |
| *printf("->%d<-\n", i);
| |
| *printf("->%4d<-\n", i);
| |
| *printf("->%5d<-\n", i);
| |
| Bei der Ausgabe von Fließkommazahlen kann zusätzlich zur Länge des Ausgabebereichs die Anzahl der Nachkommastellen eingestellt werden:
| |
| *float f = 123.625;
| |
| *printf("->%f<-\n", f);
| |
| *printf("->%.2f<-\n", f);
| |
| *printf("->%10.0f<-\n", f);
| |
| *printf("->%10.1f<-\n", f);
| |
| *printf("->%10.2f<-\n", f);
| |
| *printf("->%10.3f<-\n", f);
| |
| *printf("->%10.4f<-\n", f)
| |
| ==Beispielskript==
| |
| <syntaxhighlight>
| |
| #!/bin/bash
| |
| for DIR in $(df -t ext4 | awk 'NR>1 { print $6 }')
| |
| do
| |
| PROZENT=$(df -t ext4 $DIR | awk 'NR>1 { print $5 }')
| |
| PRO=$(echo $PROZENT | tr -d "%")
| |
| let KI=PRO*20/100
| |
| let MI=20-KI
| |
| K="####################"
| |
| M='--------------------'
| |
| printf "%-10s%-4s%.${KI}s%.${MI}s" $DIR $PROZENT $K $M
| |
| echo
| |
| done
| |
| </syntaxhighlight>
| |
| ==Links==
| |
| *https://linuxconfig.org/bash-printf-syntax-basics-with-examples
| |
| | |
| =Das neue Test Kommando=
| |
| *"[[" ist Bashs Verbesserung des "[" Befehls.
| |
| *Es ist die bessere Wahl, wenn Sie Skripte schreiben, die auf Bash abzielen. Meine Favoriten sind:
| |
| *Es ist eine syntaktische Funktion der Shell, daher weist sie ein besonderes Verhalten auf, das "[" nicht hat.
| |
| *Variablen müssen nicht mehr quotiert werden, da leere Zeichenfolgen und Zeichenfolgen mit Leerzeichen intuitiver behandelt werden.
| |
| *Zum Beispiel müssen Sie mit "[" schreiben.
| |
| <pre>
| |
| if [ -f "$ FILE"]
| |
| </pre>
| |
| *um leere Zeichenfolgen oder Dateinamen mit Leerzeichen richtig zu behandeln. Mit "[[" sind die Anführungszeichen unnötig:
| |
| <pre>
| |
| if [[ -f $ FILE ]]
| |
| </pre>
| |
| *Da es sich um eine syntaktische Funktion handelt, können Sie && und || verwenden Operatoren für Boolesche Tests und <und> für Zeichenfolgenvergleiche.
| |
| *[ kann dies nicht tun, da es sich um einen regulären Befehl handelt und &&, ||, <und> nicht als Befehlszeilenargumente an reguläre Befehle übergeben werden.
| |
| | |
| *Es hat einen wunderbaren Operator = ~, um Übereinstimmungen mit regulären Ausdrücken zu erstellen. Mit [ könntest du schreiben
| |
| <pre>
| |
| if ["$ ANSWER" = y -o "$ ANSWER" = yes]
| |
| </pre>
| |
| *Mit [[ können Sie dies als schreiben
| |
| <pre>
| |
| if [[ $ ANSWER = ~ ^ y (es)? ]]
| |
| </pre>
| |
| *Sie können sogar auf die erfassten Gruppen zugreifen, die in BASH_REMATCH gespeichert sind.
| |
| *Zum Beispiel wäre $ {BASH_REMATCH [1]} "es", wenn Sie oben ein vollständiges "ja" eingeben.
| |
| *Sie erhalten die Mustererkennung aka Globbing kostenlos.
| |
| *Vielleicht sind Sie weniger streng im Schreiben von Ja. Vielleicht bist du okay, wenn der Benutzer y-irgendetwas eingibt. Haben Sie sich versichert:
| |
| *wenn $ ANSWER = y *
| |
| | |
| =Links= | |
| *http://openbook.rheinwerk-verlag.de/shell_programmierung/ | |
| *http://mywiki.wooledge.org/BashFAQ/031 | |
| *http://tldp.org/LDP/abs/html/index.html | |
| *http://openbook.rheinwerk-verlag.de/shell_programmierung/shell_006_003.htm | |
| *https://kuepper.userweb.mwn.de/informatik/printf.pdf | |