Bash Programmierung: Unterschied zwischen den Versionen

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen
 
(69 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
−
=Bash Basics=
+
=Allgemeines=
−
*[[Einfache Shellsonderzeichen]]
+
*[[Thomas Will]]
−
*[[Bash Eingabe/Ausgabe]]
+
*[[Zeiten]]
−
*[[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]]
−
*[[read-Kommando]]
+
* [[Skript Interpreten in Linux]]
−
*[[Einfache Verzweigungen]]
+
* [[Möglichkeiten ein Shellskript aufzurufen]]
−
*[[Endestatus]]
+
* [[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]]
  
−
*[[test-Kommando]]
+
= Links=
−
 
+
* http://openbook.rheinwerk-verlag.de/shell_programmierung/
−
=Optionen der Shell=
+
* http://mywiki.wooledge.org/BashFAQ/031
−
Die Shell hat verschiedene sehr nützliche Optionen.
+
* http://tldp.org/LDP/abs/html/index.html
−
 
+
* http://openbook.rheinwerk-verlag.de/shell_programmierung/shell_006_003.htm
−
=Man kann sie sich mit Optionen den aktuellen Shell anzeigen lassen=
+
* https://kuepper.userweb.mwn.de/informatik/printf.pdf
−
*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 Ganzzahlarithme­tik.
 
−
*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
 

Aktuelle Version vom 12. Oktober 2025, 19:14 Uhr