Bash: Unterschied zwischen den Versionen

Aus xinux.net
Zur Navigation springen Zur Suche springen
 
(44 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
==Prinzip==
+
=Bash Basics=
 +
==Einfache Shellsonderzeichen==
 +
{| class="wikitable" border="1" cellpadding="2"
 +
|-
 +
|;
 +
|Trenne Kommandos
 +
|-
 +
|#
 +
|Kommentar
 +
|-
 +
|&
 +
|Programm im Hintergrund starten
 +
|-
 +
|<nowiki>|</nowiki>
 +
|STOUT von links wird zu STDIN von rechts
 +
|-
 +
|*
 +
|steht für beliebig viel Zeichen auch 0
 +
|-
 +
|?
 +
|steht für genau ein Zeichen
 +
|-
 +
|[abc]
 +
|steht für eins der Zeichen in [ ] hier a b oder c
 +
|-
 +
|~
 +
|das Homeverzeichnis
 +
|-
 +
|>    und    >>
 +
|leite in Datei um  >  überschreibe    >> hänge an
 +
|-
 +
|<
 +
|lesen aus Datei
 +
|-
 +
|2>&1
 +
|leite STDERR auf STDOUT
 +
|-
 +
|<< ende
 +
|Lesen aus Datei (Heredokument)
 +
|-
 +
|{ ,  ,  , }
 +
|Zeichenketten zusammensetzen
 +
|-
 +
|"..."
 +
|Entwertung der Sonderzeichen ausser $ ' \
 +
|-
 +
|'...'
 +
|Entwertung sämtlicher Sonderzeichen ausser ' selbst
 +
|-
 +
|\ 
 +
|Entwertung des folgenden Sonderzeichens
 +
|-
 +
|}
 +
 
 +
 
 +
==Eingabe/Ausgabe==
 +
Standardeingabe (0): Laufende Programme erwarten von hier ihre Eingaben (normalerweise handelt es sich um die Tastatur).
 +
 
 +
Standardausgabe (1): Programme schreiben auf diese ihre Ausgaben (Bildschirm).
 +
 
 +
Standardfehlerausgabe (2) : Fehlerausgaben landen hier (Bildschirm, aber nur die aktive Konsole).
 +
 
 +
[[Bild:std.jpg]]
 +
 
 +
==Umleitungen==
 +
;cat
 +
Das Programm cat liest von STDIN und gibt es STDOUT wieder aus, solange bis das EOF Zeichen kommt.
 +
*cat
 +
bla bla
 +
bla bla
 +
 
 +
Einlesen der Datei dat
 +
*cat < dat
 +
wichtig
 +
 
 +
Schreiben in die Datei dat, dies überschreibt den bisherigen Inhalt der Datei
 +
*cat > dat
 +
sogar noch wichtiger
 +
 +
Ausgeben der Datei text
 +
*cat dat
 +
sogar noch wichtiger
 +
 
 +
Lesen aus der Datei dat und schreiben in die Datei neuedat
 +
*cat < dat > neuedat
 +
*cat < neuedat
 +
sogar noch wichtiger
 +
 
 +
Anhängen der Ausgabe von date an die Datei neuedat
 +
*date >> neuedat
 +
*cat neuedat
 +
sogar noch wichtiger
 +
Do 18. Jun 14:08:58 CEST 2009
 +
 
 +
Umleiten des Standardfehlerkanals nach error
 +
*rm sux 2> error
 +
*more error
 +
Entfernen von „sux“ nicht möglich: No such file or directory
 +
 
 +
Zusammenlegen von Standardausgabe und des Standardfehlerkanals
 +
*touch tux
 +
*rm -v sux tux > aus-err 2>&1
 +
*cat < aus-err
 +
rm: Entfernen von „sux“ nicht möglich: No such file or directory
 +
„tux“ entfernt
 +
 
 +
==Nacheinander auszuführende Kommandos==
 +
*pwd; date
 +
/root
 +
Do 18. Jun 14:13:05 CEST 2009
 +
 +
Verknüpfung von cat und wc 
 +
*cat < aus-err | wc -l
 +
2
 +
 
 +
Übergeben der Ausgabe von tail als Eingabe von grep mit Hilfe der Pipe "|"
 +
*tail /var/log/auth.log | grep xinux
 +
Jun 18 13:52:33 zero nss_wins[11433]: pam_unix(login:session): session closed for user xinux
 +
 
 +
Übergeben der letzten 100 Zeilen von syslog als Eingabe von grep
 +
*tail /var/log/syslog -n 100 | grep error
 +
Jun 18 09:30:54 zero kernel: [154384.692135] end_request: I/O error, dev fd0, sector 0
 +
Jun 18 09:30:54 zero kernel: [154384.712137] end_request: I/O error, dev fd0, sector 0
 +
 
 +
==Jokerzeichen in der Shell==
 +
*mkdir test
 +
*cd test/
 +
*touch a ab abc abcd abcd b cd efg haij
 +
Ein * steht für jedes Zeichen beliebig oft
 +
*ls *
 +
a  ab  abc  abcd b  cd  efg  haij
 +
*ls ab*
 +
ab  abc  abcd
 +
Ein ? steht für ein Zeichen
 +
*ls ?
 +
a b
 +
*ls ??
 +
ab cd
 +
*ls ???*
 +
abc  abcd  efg haij
 +
Eine [] steht genau für ein Zeichen das in der Klammer ist
 +
*ls [ab]
 +
a  b
 +
*ls [abc]?
 +
ab  cd
 +
Eine [!] steht genau für ein Zeichen das nicht in der Klammer ist
 +
*ls [!abc]*
 +
efg  haij
 +
Mit der {element1,element2} kann man Dateinamen generieren
 +
*mkdir -v  dir{1,2,3,4,5,6}
 +
mkdir: Verzeichnis „dir1“ angelegt
 +
mkdir: Verzeichnis „dir2“ angelegt
 +
mkdir: Verzeichnis „dir3“ angelegt
 +
mkdir: Verzeichnis „dir4“ angelegt
 +
mkdir: Verzeichnis „dir5“ angelegt
 +
mkdir: Verzeichnis „dir6“ angelegt
 +
Backup mit Dateinamengenerierung
 +
cp -v xx{,.save}
 +
 
 +
Wenn kein Treffer erfolgt wird das Sonderzeichen eingesetzt
 +
*rm -r *
 +
*mkdir -v *
 +
mkdir: Verzeichnis „*“ angelegt
 +
*cd *t/*$
 +
Entwerten kann man ein Sonderzeichen mit einem \
 +
*rm -rvi \*
 +
rm: Verzeichnis „*“ entfernen? n
 +
Entwerten kann man mehrereSonderzeichen mit ""
 +
*rm -rvi "*"
 +
rm: Verzeichnis „*“ entfernen? n
 +
Entwerten kann man mehrereSonderzeichen mit ''
 +
*rm -rvi '*'
 +
rm: Verzeichnis „*“ entfernen? n
 +
=Prinzip der Bash=
 
Auf der Konsole werden die Befehle aneinander gereiht, indem zwischen den Befehlen ein ; eingefügt wird.  
 
Auf der Konsole werden die Befehle aneinander gereiht, indem zwischen den Befehlen ein ; eingefügt wird.  
 
*date ; hostname ; pwd
 
*date ; hostname ; pwd
Zeile 14: Zeile 187:
 
  pwd
 
  pwd
  
===Die Ausgabe des Shellskriptes===
+
=Die Ausgabe des Shellskriptes=
 
*./skript
 
*./skript
 
  Mon Dec 15 09:07:22 CET 2003
 
  Mon Dec 15 09:07:22 CET 2003
Zeile 20: Zeile 193:
 
  /home/thomas/bin
 
  /home/thomas/bin
  
===Struktogramm nach Nassi-Shneiderman===
+
=Struktogramm nach Nassi-Shneiderman=
  
 
{| border=1 cellpadding="2"
 
{| border=1 cellpadding="2"
Zeile 31: Zeile 204:
 
|}
 
|}
  
===Der Interpretor in der Windowswelt===
+
=Interpretator=
 +
==Der Interpretor in der Windowswelt==
  
 
{| border=1 cellpadding="2"
 
{| border=1 cellpadding="2"
Zeile 50: Zeile 224:
 
| cmd.exe
 
| cmd.exe
 
|}
 
|}
 
+
==Der Interpretor in der Linuxwelt==
===Der Interpretor in der Linuxwelt===
 
 
Unter  Unix/Linux entscheidet nicht die Suffix welchem Interpretor ein Skript übergeben wird, da ja in  
 
Unter  Unix/Linux entscheidet nicht die Suffix welchem Interpretor ein Skript übergeben wird, da ja in  
 
der Regel keine Suffix vorhanden ist. Die Art wird durch die Datei bestimmt, und zwar durch die ersten  
 
der Regel keine Suffix vorhanden ist. Die Art wird durch die Datei bestimmt, und zwar durch die ersten  
Zeile 112: Zeile 285:
 
''(Es wird kein neuer Prozess gestartet; Variablen haben in dieser Shell Gültigkeit)''
 
''(Es wird kein neuer Prozess gestartet; Variablen haben in dieser Shell Gültigkeit)''
 
 
==Variablen==
+
=Variablen=
===Skalare Variablen===
+
==Skalare Variablen==
 
Eine Variable stellt einen Platzhalter dar. Man spricht von Variablensubstitution, wenn anstatt der  
 
Eine Variable stellt einen Platzhalter dar. Man spricht von Variablensubstitution, wenn anstatt der  
 
Variablen deren Wert bzw. Inhalt ausgegeben wird.Eine Variable muss im Gegensatz zu Programmiersprachen,  
 
Variablen deren Wert bzw. Inhalt ausgegeben wird.Eine Variable muss im Gegensatz zu Programmiersprachen,  
Zeile 133: Zeile 306:
 
*ls -ld  $UNIXSYSTEM
 
*ls -ld  $UNIXSYSTEM
 
  drwxr-xr-x 11 root root 4096 2008-10-29 23:58 /usr
 
  drwxr-xr-x 11 root root 4096 2008-10-29 23:58 /usr
===Feld Variablen===
+
==Feld Variablen==
 
Definition der Feld Variablen
 
Definition der Feld Variablen
 
*farbe=(blau gelb gruen rot)
 
*farbe=(blau gelb gruen rot)
Zeile 145: Zeile 318:
 
*echo ${farbe[3]}
 
*echo ${farbe[3]}
 
  rot
 
  rot
===Der Exportbefehl===
+
==Der Exportbefehl==
 
Die Variable wird nicht automatisch an Kindprozess weitergegeben. Mit export wird eine Variable markiert,  
 
Die Variable wird nicht automatisch an Kindprozess weitergegeben. Mit export wird eine Variable markiert,  
 
sodass sie in die Prozessumgebung übernommen wird um beim Forken auch dem Kindprozess zur Verfügung zu stehen.
 
sodass sie in die Prozessumgebung übernommen wird um beim Forken auch dem Kindprozess zur Verfügung zu stehen.
Zeile 151: Zeile 324:
 
Shellvariablen werden mit set angezeigt.
 
Shellvariablen werden mit set angezeigt.
  
===Kommandosubstitution===
+
==Kommandosubstitution==
 
Bei der Kommandosubstitution wird ein Kommando mit seinem Rückgabewert ersetzt.
 
Bei der Kommandosubstitution wird ein Kommando mit seinem Rückgabewert ersetzt.
 
Es existieren zwei Varianten  
 
Es existieren zwei Varianten  
Zeile 172: Zeile 345:
 
  09:29:58
 
  09:29:58
  
===Abgrenzen von Variablen===
+
==Abgrenzen von Variablen==
 
Folgt einem Dollarzeichen $ ein Variablenname oder eine öffnende geschweifte Klammer ${...}, so spricht man  
 
Folgt einem Dollarzeichen $ ein Variablenname oder eine öffnende geschweifte Klammer ${...}, so spricht man  
 
von einer Variablen- bzw. Parameterexpansion. Die geschweiften  Klammern dienen zur Gruppierung und sind bei
 
von einer Variablen- bzw. Parameterexpansion. Die geschweiften  Klammern dienen zur Gruppierung und sind bei
Zeile 192: Zeile 365:
 
  einszwei
 
  einszwei
  
===Weitere Mechanismen zur Parameterexpansion===
+
==Weitere Mechanismen zur Parameterexpansion==
 
Die weiteren Mechanismen zur Parameterexpansion manipulieren den Inhalt von Variablen.  "FARBE" bezeichnet  
 
Die weiteren Mechanismen zur Parameterexpansion manipulieren den Inhalt von Variablen.  "FARBE" bezeichnet  
 
nachfolgend den Variablennamen und "rot" steht entweder für eine Zeichenkette oder für eine Variable, die  
 
nachfolgend den Variablennamen und "rot" steht entweder für eine Zeichenkette oder für eine Variable, die  
Zeile 207: Zeile 380:
 
*echo $FARBE
 
*echo $FARBE
 
  gruen
 
  gruen
 
+
*${FARBE:=rot}
* ${FARBE:=rot}
 
  
 
Wenn die Variable $FARBE definiert ist, wird der Inhalt zurückgeliefert, wenn sie nicht definiert ist, wird  
 
Wenn die Variable $FARBE definiert ist, wird der Inhalt zurückgeliefert, wenn sie nicht definiert ist, wird  
Zeile 316: Zeile 488:
 
  blauweisblau
 
  blauweisblau
  
==Besondere Dateien==
+
=Besondere Dateien=
; /etc/profile
+
*[[Bash Dateien]]
Wird beim Anmelden automatisch ausgeführt. Sie gilt für alle.
 
; ~/.bash_profile
 
Wenn diese Datei existiert, wird sie beim Anmelden automatisch ausgeführt; sonst springe zu ~/.bash_login
 
  
; ~/.bash_login
+
=Wichtige Systemvariablen (Auswahl)=
Wenn diese Datei existiert wird sie beim Anmelden automatisch ausgeführt ;sonst springe zu ~/.profile
+
*[[Bash Wichtige Systemvariablen (Auswahl)]]
  
; ~/.profile
+
=Stellungsparameter (Spezielle Variablen)=
Wird beim Anmelden automatisch ausgeführt wenn die beiden obigen nicht existieren.
 
 
 
; ~/.bashrc
 
Wird beim starten jeder Bash automatisch ausgeführt.
 
 
 
; ~/.bash_history
 
Enthält die während der letzten Sitzung eingegebenen Befehle
 
 
 
; ~/.bash_logout
 
Wird beim Abmelden ausgeführt
 
 
 
==Wichtige Systemvariablen (Auswahl)==
 
; PATH
 
Pfad, in dem nach ausführbaren Programmen gesucht wird
 
; HOME
 
Heimatverzeichnis
 
; BASH
 
Pfadname der aktuellen Shell
 
; PWD
 
Aktuelles Verzeichnis
 
; OLDPWD
 
Letztes aktuelles Verzeichnis vor cd
 
; PS1 ,PS2 , PS3
 
Eingabeprompt 1 2 und 3
 
; UID
 
Benutzerkennung
 
; EDITOR
 
Standardeditor (wenn nicht belegt, dann vi)
 
; MAIL
 
Dort werden die Mails gespeichert
 
; HOSTNAME
 
Name des Rechners
 
 
 
==Stellungsparameter (Spezielle Variablen)==
 
 
Den Stellungsparametern $1, $2, ..., $9 werden bei ihrer Definition nach ihrer Reihenfolge Werte zugewiesen.  
 
Den Stellungsparametern $1, $2, ..., $9 werden bei ihrer Definition nach ihrer Reihenfolge Werte zugewiesen.  
 
Die Definition erfolgt mit dem Kommando ''set',  einem Skript - oder Prozeduraufruf .  
 
Die Definition erfolgt mit dem Kommando ''set',  einem Skript - oder Prozeduraufruf .  
Zeile 365: Zeile 500:
 
Ihr Geltungsbereich ist lokal, d.h. sie gelten nur in der aktuellen bash und können nicht exportiert werden.
 
Ihr Geltungsbereich ist lokal, d.h. sie gelten nur in der aktuellen bash und können nicht exportiert werden.
  
===Belegen der Variablen mittels set===
+
==Belegen der Variablen mittels set==
 
*set der fck ist eine klasse Mannschaft
 
*set der fck ist eine klasse Mannschaft
 
*echo $1 $2 $3
 
*echo $1 $2 $3
Zeile 375: Zeile 510:
 
  unser fcs ist
 
  unser fcs ist
  
===Belegen der Variablen durch einen Skriptaufruf===
+
==Belegen der Variablen durch einen Skriptaufruf==
 
Die Variablen werden automatisch beim Skriptaufruf belegt, indem sie als Argumente dem Skript übergeben werden.
 
Die Variablen werden automatisch beim Skriptaufruf belegt, indem sie als Argumente dem Skript übergeben werden.
 
*cat skript1
 
*cat skript1
Zeile 449: Zeile 584:
 
  von der schule hier
 
  von der schule hier
  
==read-Kommando==
+
=Here Dokument=
 +
Heredocs dienen zur Definition von Textabschnitten. Im Unterschied zur herkömmlichen Ausgabe per echo  werden enthaltene Zeilenumbrüche, Einzüge und einige Sonderzeichen im Text bewahrt. Die Bash ermöglicht auch die Verwendung von Variablen innerhalb des Heredoc.
 +
 
 +
Der Block ab "cat<<HERE" wird bis zu "HERE" ausgegeben. Das Wort "HERE" ist beliebig. Wichtig hinter dem 2 Wort darf keine Leerzeichnen stehen.
 +
<syntaxhighlight lang="bash">
 +
#!/bin/bash
 +
INT=$1
 +
IP=$2
 +
NM=$3
 +
GW=$4
 +
cat<<HERE
 +
auto $INT
 +
iface $INT inet static
 +
address $IP
 +
netmask $NM
 +
gateway $GW
 +
HERE
 +
</syntaxhighlight>
 +
*./interface-gen.sh eth3 192.168.24.67 255.255.255.0 192.168.24.1
 +
<pre>
 +
auto eth3
 +
iface eth3 inet static
 +
address 192.168.24.67
 +
netmask 255.255.255.0
 +
gateway 192.168.24.1
 +
</pre>
 +
 
 +
=read-Kommando=
 
Mit read wird eine Eingabezeile eingelesen und deren Inhalt Variablen zugewiesen. Die Eingabe wird anhand der  
 
Mit read wird eine Eingabezeile eingelesen und deren Inhalt Variablen zugewiesen. Die Eingabe wird anhand der  
 
Trennzeichen in einzelne Token zerlegt und der Reihe nach den Variablen zugewiesen. Stehen mehr Token zur  
 
Trennzeichen in einzelne Token zerlegt und der Reihe nach den Variablen zugewiesen. Stehen mehr Token zur  
Zeile 462: Zeile 624:
 
read wird in dieser Form sehr selten benutzt da der automatische Charakter von shell Skripten dadurch verloren geht.
 
read wird in dieser Form sehr selten benutzt da der automatische Charakter von shell Skripten dadurch verloren geht.
  
==Einfache Verzweigungen==
+
=Einfache Verzweigungen=
 
In Abhängigkeit vom Returncode eines Befehls oder einer Pipe kann mit den Sonderzeichen ''&&'' und ''||''  eine  
 
In Abhängigkeit vom Returncode eines Befehls oder einer Pipe kann mit den Sonderzeichen ''&&'' und ''||''  eine  
 
Verzweigung durchgeführt werden.
 
Verzweigung durchgeführt werden.
Zeile 472: Zeile 634:
 
(Returncode != 0), wird der Befehl nach ''||'' ausgeführt.
 
(Returncode != 0), wird der Befehl nach ''||'' ausgeführt.
  
==Endestatus==
+
=Endestatus=
 
N:ach der Ausführung eines  Befehls wird ein Returncode (Endestatus) zurückgeliefert. Mit Hilfe des Returncodes lässt  
 
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.
 
sich feststellen, ob der letzte Befehl fehlerfrei ausgeführt wurde.
Zeile 507: Zeile 669:
 
Erkenntnis: Löschen war nicht erfolgreich
 
Erkenntnis: Löschen war nicht erfolgreich
  
==test-Kommando==
+
=test-Kommando=
 
Der eingebaute Befehl ''test'' gibt sein Ergebnis als Returncode zurück. Dieser Befehl wird daher oft in  
 
Der eingebaute Befehl ''test'' gibt sein Ergebnis als Returncode zurück. Dieser Befehl wird daher oft in  
 
Kontrollstrukturen der bash zur Verzweigung verwendet.
 
Kontrollstrukturen der bash zur Verzweigung verwendet.
Zeile 520: Zeile 682:
 
eine beliebige Kombination der vorhergehenden sein.
 
eine beliebige Kombination der vorhergehenden sein.
  
===Numerischer Vergleich===
+
==Numerischer Vergleich==
 
  '''test''' zahl1 '''-op''' zahl2 (op: eq, ne, lt, gt, ge, le)
 
  '''test''' zahl1 '''-op''' zahl2 (op: eq, ne, lt, gt, ge, le)
 
*ZAHL=4
 
*ZAHL=4
Zeile 546: Zeile 708:
 
|}
 
|}
  
===Stringvergleich===
+
==Stringvergleich==
 
  '''test''' string1 '''=''' string2
 
  '''test''' string1 '''=''' string2
 
  '''test''' string1 '''!=''' string2
 
  '''test''' string1 '''!=''' string2
Zeile 559: Zeile 721:
 
  bilbo
 
  bilbo
  
===Objekteigenschaften===
+
==Objekteigenschaften==
 
  '''test -op''' objekt    
 
  '''test -op''' objekt    
 
{| border=1 cellpadding="2"
 
{| border=1 cellpadding="2"
Zeile 570: Zeile 732:
 
| r || leserecht auf das Objekt
 
| r || leserecht auf das Objekt
 
|-
 
|-
| w || schreibrecht auf das Objekt
+
| w || schreibrecht auf das Objekt
 
|-
 
|-
 
| x || ausführungsrecht auf das Objekt
 
| x || ausführungsrecht auf das Objekt
Zeile 580: Zeile 742:
 
  so ist es richtig
 
  so ist es richtig
  
===Prioritäten bei logischen Verknüpfungen===
+
==Prioritäten bei logischen Verknüpfungen==
 
{| border=1
 
{| border=1
 
| runde Klammer || Negation || AND || OR
 
| runde Klammer || Negation || AND || OR
Zeile 594: Zeile 756:
 
*! test -r /etc/shadow &&  echo so ist es richtig
 
*! test -r /etc/shadow &&  echo so ist es richtig
 
  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==
+
=Der if-Block=
 
  '''if''' programm
 
  '''if''' programm
 
  '''then'''  
 
  '''then'''  
Zeile 625: Zeile 820:
 
  rechner ist tot
 
  rechner ist tot
  
===Variante ohne else===
+
==Variante ohne else==
 
*cat rechnertest.spar
 
*cat rechnertest.spar
 
<syntaxhighlight>
 
<syntaxhighlight>
Zeile 639: Zeile 834:
 
*./rechnertest.spar 172.20.103.99
 
*./rechnertest.spar 172.20.103.99
  
===Sonderform  mit elif===
+
==Sonderform  mit elif==
 
*cat el
 
*cat el
 
<syntaxhighlight>
 
<syntaxhighlight>
Zeile 646: Zeile 841:
 
  read NAME
 
  read NAME
 
  if test $NAME = "thomas"
 
  if test $NAME = "thomas"
then
+
  then
        echo "hallo meister"
+
    echo "hallo meister"
 
  elif test $NAME = "martin"
 
  elif test $NAME = "martin"
        then
+
  then
        echo "hallo vizemeister"
+
    echo "hallo vizemeister"
        else
+
else
        echo "hallo wurm"
+
    echo "hallo wurm"
 
  fi
 
  fi
 
</syntaxhighlight>
 
</syntaxhighlight>
Zeile 665: Zeile 860:
 
  hallo wurm
 
  hallo wurm
  
==Der case-Block==
+
=Der case-Block=
 
Der case-Block dient der Durchführung eines Stringvergleiches. Er wird sequentiell von oben nach unten abgearbeitet. Bei  
 
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  
 
Übereinstimmungen mit einem definierten Muster wird der darauf folgende Befehl ausgeführt (bzw. die darauf folgende  
Zeile 702: Zeile 897:
 
  kein bock auf musik
 
  kein bock auf musik
  
==Rechnen mit der Bash==
+
=Rechnen mit der Bash=
 
; '''$(())'''
 
; '''$(())'''
 
; '''expr'''
 
; '''expr'''
 
; '''bc'''
 
; '''bc'''
===Arithmetische Substitution===
+
==Arithmetische Substitution==
 
Die $(()) oder $[ ] ist die arithmetische Erweiterungsmethode  der Bash.
 
Die $(()) oder $[ ] ist die arithmetische Erweiterungsmethode  der Bash.
 
*echo $((7+5))
 
*echo $((7+5))
Zeile 720: Zeile 915:
 
*ZAHL=5 ; ZAHL=$(($ZAHL + 1)) ; echo $ZAHL
 
*ZAHL=5 ; ZAHL=$(($ZAHL + 1)) ; echo $ZAHL
 
  6
 
  6
===Der expr-Befehl===
+
==Der expr-Befehl==
 
Erlaubt die Durchführung komplexer Stringoperationen und Ganzzahlarithme­tik.
 
Erlaubt die Durchführung komplexer Stringoperationen und Ganzzahlarithme­tik.
 
*expr 7 + 5
 
*expr 7 + 5
Zeile 734: Zeile 929:
 
*ZAHL=5 ; ZAHL=$(expr $ZAHL + 1) ; echo $ZAHL
 
*ZAHL=5 ; ZAHL=$(expr $ZAHL + 1) ; echo $ZAHL
 
  6
 
  6
===bc - interaktiver Taschenrechner===
+
==bc - interaktiver Taschenrechner==
 
*bc
 
*bc
 
  bc 1.06
 
  bc 1.06
Zeile 763: Zeile 958:
 
  6
 
  6
  
== Die while-Schleife ==
+
=Die while-Schleife=
 +
==Einfache Form==
 
Die while-Schleife wird so lange durchlaufen, bis der Returncode ungleich null ist.
 
Die while-Schleife wird so lange durchlaufen, bis der Returncode ungleich null ist.
 
*cat proggi
 
*cat proggi
Zeile 807: Zeile 1.003:
 
  BUMM BUMM
 
  BUMM BUMM
  
===Sonderform von while===
+
==Sonderform von while==
 
Die Variable SUX wird nacheinander mit jeder Zeile der Datei  
 
Die Variable SUX wird nacheinander mit jeder Zeile der Datei  
 
/etc/passwd belegt, bis die letzte Zeile der Datei /etc/passwd erreicht ist.
 
/etc/passwd belegt, bis die letzte Zeile der Datei /etc/passwd erreicht ist.
Zeile 840: Zeile 1.036:
 
  done
 
  done
 
</syntaxhighlight>
 
</syntaxhighlight>
==Die until-Schleife==
+
=Die until-Schleife=
  
 
Die until-Schleife wird so lange durchlaufen, bis der Returncode der Abbruchbedingung gleich null ist.
 
Die until-Schleife wird so lange durchlaufen, bis der Returncode der Abbruchbedingung gleich null ist.
Zeile 854: Zeile 1.050:
 
[[Image:until.jpg]]
 
[[Image:until.jpg]]
  
== Die for-Schleife ==
+
= Die for-Schleife =
===Standard For Schleife===
+
==Standard For Schleife==
 
Bei der for-Schleife wird bei jedem Durchlauf der Schleifenvariablen ein Wert aus einer angegebenen Liste  
 
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  
 
zugewiesen; die Liste wird dabei von links nach rechts durchlaufen. Nach der letzten Wertzuweisung terminiert die  
Zeile 863: Zeile 1.059:
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
 
  #!/bin/bash
 
  #!/bin/bash
  for CLUB in fck bvb fcs
+
  for CLUB in fck bvb schalke bmg
 
   do
 
   do
 
   echo $CLUB
 
   echo $CLUB
Zeile 871: Zeile 1.067:
 
  fck
 
  fck
 
  bvb
 
  bvb
  fcs
+
  schalke
 +
bmg
  
 
Darstellung als Struktogramm nach Nassi / Shneiderman:
 
Darstellung als Struktogramm nach Nassi / Shneiderman:
Zeile 877: Zeile 1.074:
 
[[Image:for.jpg]]
 
[[Image:for.jpg]]
  
===For Schleife mit Stellungsparametern===
+
==For Schleife mit Stellungsparametern==
 
Wird keine Liste angegeben, wird standardmäßig die Liste der Stellungsoperanden benutzt. Folgende Anweisungen sind äquivalent  
 
Wird keine Liste angegeben, wird standardmäßig die Liste der Stellungsoperanden benutzt. Folgende Anweisungen sind äquivalent  
 
<syntaxhighlight>
 
<syntaxhighlight>
Zeile 894: Zeile 1.091:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===For Schleife mit Dateien aus dem aktuellen Verzeichnis===
+
==For Schleife mit Dateien aus dem aktuellen Verzeichnis==
 
Der Stern würde durch alle Dateien des aktuellen Verzeichnisses ersetzt werden.
 
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  
 
Daraus folgt, dass der Name jeder Datei nacheinander in die Variable LAUF geschreiben wird. Die Anzahl der Schleifenläufe  
Zeile 913: Zeile 1.110:
 
done
 
done
 
</syntaxhighlight>
 
</syntaxhighlight>
===For Schleife im C Stil===
+
==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:  
 
Mit Bash-Version 2.0.4 wurde die for-Schleife um eine an die Programmier-sprache C angelehnte Syntaxvariante erweitert:  
  
  for ((Initialisierung der Laufvaribale; Abbruchbedingung; Veränderung der Laufvariable))
+
  for ((Initialisierung der Laufvaribale; Laufbedingung; Veränderung der Laufvariable))
 
  do  
 
  do  
 
  Kommando
 
  Kommando
Zeile 934: Zeile 1.131:
 
  4
 
  4
  
==Steuerung der Ablaufanweisungen==
+
=Steuerung der Ablaufanweisungen=
===exit n===
+
==exit n==
 
Der aktuelle Prozess und damit auch die bash werden abgebrochen. Für n kann eine Zahl zwischen 0 und 255 angegeben werden;  
 
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.
 
damit kann der Returncode des Prozesses festgelegt werden, der an den aufrufenden Prozess übergeben wird.
Zeile 942: Zeile 1.139:
 
Schlüsselwörtern ''do'' und ''done'' stehen.
 
Schlüsselwörtern ''do'' und ''done'' stehen.
  
===continue n===
+
==continue n==
 
Der aktuelle Schleifendurchlauf wird abgebrochen, um mit dem nächsten Durchlauf zu beginnen. Bei Verschachtelungen kann  
 
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.
 
durch Angabe einer Ganzzahl in der n-ten Schleifenebene angesetzt werden.
Zeile 964: Zeile 1.161:
 
  fcs
 
  fcs
  
===break n===
+
=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  
 
Die aktuelle Schleife wird abgebrochen, danach wird mit der ersten Anweisung nach der Schleife weitergemacht. Bei  
 
Verschachtelungen wird auf der n-ten Schleifenebene aufgesetzt.
 
Verschachtelungen wird auf der n-ten Schleifenebene aufgesetzt.
Zeile 982: Zeile 1.221:
 
  echo  "und tschuess"
 
  echo  "und tschuess"
 
</syntaxhighlight>
 
</syntaxhighlight>
==Funktionen==
 
Eine Funktion ist ein Name für ein Kommando oder für eine Gruppe von Kommandos. Funktionen werden vorrangig in Shellskripten
 
verwendet, um wiederkehrende Kommandosequenzen nicht ständig neu schreiben zu müssen. Ein großer Vorteil von Funktionen ist,
 
dass sie sich in einer Datei speichern lassen und diese Datei von anderen Skripten geladen werden kann (sourcen).
 
  
Eine Funktion wird wie folgt definiert:
+
=Funktionen=
Format: [function] Funktionsname() { Kommando; [Kommando;] }
+
[[bash funktion]]
  
Bei der Verwendung von Funktionen sind einige Regeln zu befolgen:
+
=Signalbehandlung=
 
+
==Signale bei der Programmierung der bash==
#Deckt sich der Name der Funktion mit einem builtin-Kommando, wird immer die Funktion ausgeführt und niemals das Kommando. Ebenso verdeckt ein Funktionsname ein gleichnamiges Kommando. (ausser man benutzt das Kommando builtin)
 
#Die Funktion muss vor ihrer Verwendung definiert sein.
 
#Eine Funktion läuft in der aktuellen Umgebung, d.h. alle Variablen der Umgebung sind sichtbar und alle Variablen, die in der Funktion definiert wurden, sind auch außerhalb sichtbar
 
#Wird eine Funktion mittels "exit" verlassen, wird auch der rufende Prozess beendet
 
#Der Rückgabewert einer Funktion ist der Rückgabewert des letzten in ihr gestarteten Kommandos
 
#Funktionen sind nur in der Shell ihrer Definition bekannt
 
#return bewirkt das Verlassen der Funktion, auch mit return kann ein Rückgabewert mitgegeben werden
 
===Funktionen mit Parameter===
 
<syntaxhighlight>
 
#!/bin/bash
 
FAILED=$(echo -e "\e[31mfailed\e[39m")
 
OK=$(echo -e "\e[32mok\e[39m")
 
function status()
 
{
 
if ping -w 1 -c 1 -q $2 > /dev/null
 
then
 
  echo "$1 $2  $OK"
 
else
 
  echo "$1 $2  $FAILED"
 
fi
 
}
 
function portstatus()
 
{
 
if nc -w 1 -z $2 $3  > /dev/null
 
then
 
  echo "$1 ip: $2 port: $3 $OK "
 
else
 
  echo "$1 ip: $2 port: $3 $FAILED "
 
fi
 
}
 
status google www.google.de
 
portstatus google-http  www.google.de 80
 
portstatus google-https  www.google.de 443
 
</syntaxhighlight>
 
 
 
===Einfache Funktion===
 
<syntaxhighlight>
 
#!/bin/bash
 
function sux ()
 
{
 
echo "ich bin eine suxer funktion"
 
}
 
sux
 
</syntaxhighlight>
 
 
 
===Rekursive Funktion===
 
<syntaxhighlight>
 
#!/bin/bash
 
fac()
 
{
 
    if [ $1 -le 1 ]
 
    then
 
        echo 1
 
    else
 
        ERG=$(fac $(($1-1)))
 
        echo $(($1 * $ERG))
 
    fi
 
}
 
fac $1
 
</syntaxhighlight>
 
 
 
==Signalbehandlung==
 
===Signale bei der Programmierung der bash===
 
 
Es existieren verschiedene Möglichkeiten, auf welchem Wege Signale gesendet werden können:
 
Es existieren verschiedene Möglichkeiten, auf welchem Wege Signale gesendet werden können:
  
Zeile 1.090: Zeile 1.262:
 
|}
 
|}
  
===Reaktion eines Prozesses auf den Empfang eines Signals===
+
==Reaktion eines Prozesses auf den Empfang eines Signals==
 
* Der Prozess beendet sich (meist Standardeinstellung).
 
* Der Prozess beendet sich (meist Standardeinstellung).
 
* Der Prozess ignoriert das Signal. (Ausnahme: SIGKILL)
 
* Der Prozess ignoriert das Signal. (Ausnahme: SIGKILL)
 
* Der Prozess fängt das Signal ab, d.h. er leitet eine selbst definierte Reaktion ein.
 
* Der Prozess fängt das Signal ab, d.h. er leitet eine selbst definierte Reaktion ein.
  
==Der Befehl trap ==
+
=Der Befehl trap =
 
'''Funktionen:'''
 
'''Funktionen:'''
  
Zeile 1.127: Zeile 1.299:
 
Bemerkung: Die Signalbehandlung selbst wird nicht an Kindprozesse weitervererbt. Das Ignorieren von Signalen hingegen wird weitervererbt.
 
Bemerkung: Die Signalbehandlung selbst wird nicht an Kindprozesse weitervererbt. Das Ignorieren von Signalen hingegen wird weitervererbt.
  
== Weitere Möglichkeiten der Bash-Shell ==
+
=Weitere Möglichkeiten der Bash-Shell=
===Alias-Namen===
+
==Alias-Namen==
Mit dem Befehl ''alias'' bzw. ''unalias'' können zusätzliche Namen für Befehle Befehle vergeben bzw. entfernt werden. Dazu wird ein Name und eine zugehörige Zeichenkette vergeben.
+
*[[aliase]]
  
Beides wird in einer Liste abgelegt; bei der Interpretation einer Zeile wird der Aliasname durch die Zeichenkette ersetzt.
+
=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
  
Beispiele:
+
==Gleichzeitiges Lesen aus verschiedenen Dateien==
  alias Die bereits definierten Aliasnamen werden aufgelistet.
+
<syntaxhighlight>
  <nowiki>alias ll='ls -l''</nowiki> Definition eines neuen Aliasnamens.
+
#!/bin/bash
alias -x w='who' Definieren und Exportieren eines Alias.
+
exec 3< /etc/passwd
unalias ll Entfernen eines Alias aus der Liste.
+
exec 4< /etc/shadow
 
+
while true
Bemerkungen:
+
  do
Am Anfang eines Aliasnamens sind keine Metazeichen erlaubt.
+
  read var3 <&3
Kommt derselbe Name innerhalb der zugewiesenen Zeichenkette noch
+
  read var4 <&4
einmal vor, so wird er nicht ersetzt.
+
  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=
 
=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.
 
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.
Zeile 1.192: Zeile 1.399:
  
 
=getopts=
 
=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
 
*http://openbook.galileocomputing.de/shell_programmierung/shell_005_007.htm
  
=Das neue Test Kommando=
+
=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:
  
"[[" ist Bashs Verbesserung des "[" Befehls. Es hat mehrere Veränderungen, die es zu einer besseren Wahl machen, wenn Sie Skripte schreiben, die auf Bash abzielen. Meine Favoriten 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
  
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.
+
=Das neue Test Kommando=
<syntaxhighlight lang="bash">
+
*"[[" 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"]
 
if [ -f "$ FILE"]
</syntaxhighlight>
+
</pre>
um leere Zeichenfolgen oder Dateinamen mit Leerzeichen richtig zu behandeln. Mit "[[" sind die Anführungszeichen unnötig:
+
*um leere Zeichenfolgen oder Dateinamen mit Leerzeichen richtig zu behandeln. Mit "[[" sind die Anführungszeichen unnötig:
<syntaxhighlight>
+
<pre>
 
if [[ -f $ FILE ]]
 
if [[ -f $ FILE ]]
</syntaxhighlight>
+
</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.
+
*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
+
*Es hat einen wunderbaren Operator = ~, um Übereinstimmungen mit regulären Ausdrücken zu erstellen. Mit [ könntest du schreiben
<syntaxhighlight>
+
<pre>
 
if ["$ ANSWER" = y -o "$ ANSWER" = yes]
 
if ["$ ANSWER" = y -o "$ ANSWER" = yes]
</syntaxhighlight>
+
</pre>
Mit [[können Sie dies als schreiben
+
*Mit [[ können Sie dies als schreiben
<syntaxhighlight>
+
<pre>
 
if [[ $ ANSWER = ~ ^ y (es)? ]]
 
if [[ $ ANSWER = ~ ^ y (es)? ]]
</syntaxhighlight>
+
</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 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:
+
*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 *
+
*wenn $ ANSWER = y *
  
 
=Links=
 
=Links=
 +
*http://openbook.rheinwerk-verlag.de/shell_programmierung/
 
*http://mywiki.wooledge.org/BashFAQ/031
 
*http://mywiki.wooledge.org/BashFAQ/031
 
*http://tldp.org/LDP/abs/html/index.html
 
*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 14. November 2023, 08:07 Uhr

Bash Basics

Einfache Shellsonderzeichen

; Trenne Kommandos
# Kommentar
& Programm im Hintergrund starten
| STOUT von links wird zu STDIN von rechts
* steht für beliebig viel Zeichen auch 0
? steht für genau ein Zeichen
[abc] steht für eins der Zeichen in [ ] hier a b oder c
~ das Homeverzeichnis
> und >> leite in Datei um > überschreibe >> hänge an
< lesen aus Datei
2>&1 leite STDERR auf STDOUT
<< ende Lesen aus Datei (Heredokument)
{ , , , } Zeichenketten zusammensetzen
"..." Entwertung der Sonderzeichen ausser $ ' \
'...' Entwertung sämtlicher Sonderzeichen ausser ' selbst
\ Entwertung des folgenden Sonderzeichens


Eingabe/Ausgabe

Standardeingabe (0): Laufende Programme erwarten von hier ihre Eingaben (normalerweise handelt es sich um die Tastatur).

Standardausgabe (1): Programme schreiben auf diese ihre Ausgaben (Bildschirm).

Standardfehlerausgabe (2) : Fehlerausgaben landen hier (Bildschirm, aber nur die aktive Konsole).

Std.jpg

Umleitungen

cat

Das Programm cat liest von STDIN und gibt es STDOUT wieder aus, solange bis das EOF Zeichen kommt.

  • cat
bla bla
bla bla

Einlesen der Datei dat

  • cat < dat
wichtig

Schreiben in die Datei dat, dies überschreibt den bisherigen Inhalt der Datei

  • cat > dat
sogar noch wichtiger 

Ausgeben der Datei text

  • cat dat
sogar noch wichtiger

Lesen aus der Datei dat und schreiben in die Datei neuedat

  • cat < dat > neuedat
  • cat < neuedat
sogar noch wichtiger

Anhängen der Ausgabe von date an die Datei neuedat

  • date >> neuedat
  • cat neuedat
sogar noch wichtiger
Do 18. Jun 14:08:58 CEST 2009

Umleiten des Standardfehlerkanals nach error

  • rm sux 2> error
  • more error
Entfernen von „sux“ nicht möglich: No such file or directory

Zusammenlegen von Standardausgabe und des Standardfehlerkanals

  • touch tux
  • rm -v sux tux > aus-err 2>&1
  • cat < aus-err
rm: Entfernen von „sux“ nicht möglich: No such file or directory
„tux“ entfernt

Nacheinander auszuführende Kommandos

  • pwd; date
/root
Do 18. Jun 14:13:05 CEST 2009

Verknüpfung von cat und wc

  • cat < aus-err | wc -l
2

Übergeben der Ausgabe von tail als Eingabe von grep mit Hilfe der Pipe "|"

  • tail /var/log/auth.log | grep xinux
Jun 18 13:52:33 zero nss_wins[11433]: pam_unix(login:session): session closed for user xinux

Übergeben der letzten 100 Zeilen von syslog als Eingabe von grep

  • tail /var/log/syslog -n 100 | grep error
Jun 18 09:30:54 zero kernel: [154384.692135] end_request: I/O error, dev fd0, sector 0
Jun 18 09:30:54 zero kernel: [154384.712137] end_request: I/O error, dev fd0, sector 0

Jokerzeichen in der Shell

  • mkdir test
  • cd test/
  • touch a ab abc abcd abcd b cd efg haij

Ein * steht für jedes Zeichen beliebig oft

  • ls *
a  ab  abc  abcd b  cd  efg  haij
  • ls ab*
ab  abc  abcd

Ein ? steht für ein Zeichen

  • ls ?
a b
  • ls ??
ab cd 
  • ls ???*
abc  abcd  efg	haij

Eine [] steht genau für ein Zeichen das in der Klammer ist

  • ls [ab]
a  b
  • ls [abc]?
ab  cd

Eine [!] steht genau für ein Zeichen das nicht in der Klammer ist

  • ls [!abc]*
efg  haij

Mit der {element1,element2} kann man Dateinamen generieren

  • mkdir -v dir{1,2,3,4,5,6}
mkdir: Verzeichnis „dir1“ angelegt
mkdir: Verzeichnis „dir2“ angelegt
mkdir: Verzeichnis „dir3“ angelegt
mkdir: Verzeichnis „dir4“ angelegt
mkdir: Verzeichnis „dir5“ angelegt
mkdir: Verzeichnis „dir6“ angelegt

Backup mit Dateinamengenerierung

cp -v xx{,.save}

Wenn kein Treffer erfolgt wird das Sonderzeichen eingesetzt

  • rm -r *
  • mkdir -v *
mkdir: Verzeichnis „*“ angelegt
  • cd *t/*$

Entwerten kann man ein Sonderzeichen mit einem \

  • rm -rvi \*
rm: Verzeichnis „*“ entfernen? n

Entwerten kann man mehrereSonderzeichen mit ""

  • rm -rvi "*"
rm: Verzeichnis „*“ entfernen? n

Entwerten kann man mehrereSonderzeichen mit

  • rm -rvi '*'
rm: Verzeichnis „*“ entfernen? n

Prinzip der Bash

Auf der Konsole werden die Befehle aneinander gereiht, indem zwischen den Befehlen ein ; eingefügt wird.

  • date ; hostname ; pwd
Mon Dec 15 08:59:13 CET 2003
dozent
/home/thomas

Neben dieser interaktiven Eingabe gibt es auch die Möglichkeit, dass die Shell die Kommandos aus einer Datei lesen kann.

Der Inhalt eines (z.B. mit dem vi erstellten) Shellskriptes:

  • cat skript
date
hostname
pwd

Die Ausgabe des Shellskriptes

  • ./skript
Mon Dec 15 09:07:22 CET 2003
dozent
/home/thomas/bin

Struktogramm nach Nassi-Shneiderman

Ausgabe Datum
Ausgabe Rechnername
Ausgabe Arbeitszverzeichnis

Interpretator

Der Interpretor in der Windowswelt

Endung Interpretor
.pl Perl
.py Python
.bat command.com
.cmd cmd.exe

Der Interpretor in der Linuxwelt

Unter Unix/Linux entscheidet nicht die Suffix welchem Interpretor ein Skript übergeben wird, da ja in der Regel keine Suffix vorhanden ist. Die Art wird durch die Datei bestimmt, und zwar durch die ersten Bytes einer Datei. Wenn wir unser Skript mit

  • file skript
skript: ASCII text

untersuchen sehen wir, dass es als normaler ASCII Text interpretiert wird. Bei einem Programmaufruf wird es einfach der aktuellen Shell übergeben (es gibt ausser der bash noch andere Shells z.B. bourne-shell (bsh), korn-shell (ksh), ash). Um sicherzugehen, dass es der richtigen Shell übergeben wird, fuegt man an den Skriptanfang einfach ein #! an, in unserem Fall ein #!/bin/bash für die Bourne-Again Shell. Das bedeutet ,dass das Programm welches hinter dem #! (Gobang Operator) steht der Interpretor ist, dem das Skript übergeben wird.

#!/bin/bash
date
hostname
pwd

Selbst in der C shell ist somit sichergestellt ,dass das Skript der Bash übergeben wird

  • file skript
skript: Bourne-Again shell script text executable

Ablauf eines Shell-Skriptes

  • Starten einer Subshell
  • Lesen der Skriptdatei von der Subshell (zeilenweise)
  • Kommandos werden nacheinander abgearbeitet

Beenden der Subshell und Rückkehr zur aufrufenden Shell

Möglichkeiten ein Shellskript aufzurufen

bash skript (r)

  • Starten einer Subshell
  • Lesen der Skriptdatei von der Subshell
  • Kommandos werden nacheinander abgearbeitet
  • Beenden der Subshell und Rückkehr zur aufrufenden Shell

(Die Shell, die das Skript abarbeitet, kennt den Namen des Shellskriptes)

bash < skript (r)

  • Starten einer Subshell
  • Lesen der Skriptdatei von der Subshell
  • Kommandos werden nacheinander abgearbeitet
  • Beenden der Subshell und Rückkehr zur aufrufenden Shell

(Die Shell, die das Skript abarbeitet, kennt den Namen des Shellskriptes nicht)

./skript (rx)

  • Starten einer Subshell
  • Lesen der Skriptdatei von der Subshell
  • Kommandos werden nacheinander abgearbeitet
  • Beenden der Subshell und Rückkehr zur aufrufenden Shell

(Die Shell, die das Skript abarbeitet, kennt den Namen des Shellskriptes, es muss zusätzlich das Ausführungsrecht gesetzt sein.)

exec ./skript (rx)

  • Die Subshell ersetzt die aktuelle Shell (überlädt die aktuelle Shell)
  • Lesen der Skriptdatei von der Subshell
  • Kommandos werden nacheinander abgearbeitet
  • Beenden der Subshell; danach ist der Prozess der aufrufenden Shell beendet.

source skript oder . skript (r)

  • Lesen der Skriptdatei von der aktuellen Shell
  • Der interaktive Modus der aktuellen Shell wird „unterbrochen“
  • Kommandos werden nacheinander abgearbeitet

(Es wird kein neuer Prozess gestartet; Variablen haben in dieser Shell Gültigkeit)

Variablen

Skalare Variablen

Eine Variable stellt einen Platzhalter dar. Man spricht von Variablensubstitution, wenn anstatt der Variablen deren Wert bzw. Inhalt ausgegeben wird.Eine Variable muss im Gegensatz zu Programmiersprachen, die kompiliert werden, nicht deklariert werden, da der Interpretor zu Laufzeit den Speicherplatz allokiert (Belegung des Speicherplatzes zur Laufzeit).

Die Definition einer Variablen erfolgt durch die Nennung, gefolgt von einem = Zeichen, gefolgt von dem Inhalt, der zugewiesen wird. Wichtig : zwischen der Variablen, dem = und dem Wert darf kein Leerzeichen stehen. Man benutzt häufig Grossbuchtstaben, es sollten keine – benutzt werden.

Definition der Variable

  • GLAS=bier

Ausgabe des Variableninhalts

  • echo $GLAS
bier

Definition der Variable:

  • UNIXSYSTEM=/usr
Variablensubstititution:
  • ls -ld $UNIXSYSTEM
drwxr-xr-x 11 root root 4096 2008-10-29 23:58 /usr

Feld Variablen

Definition der Feld Variablen

  • farbe=(blau gelb gruen rot)

Ausgabe des Inhalts der Feld Variablen

  • echo ${farbe[0]}
blau
  • echo ${farbe[1]}
gelb
  • echo ${farbe[2]}
gruen
  • echo ${farbe[3]}
rot

Der Exportbefehl

Die Variable wird nicht automatisch an Kindprozess weitergegeben. Mit export wird eine Variable markiert, sodass sie in die Prozessumgebung übernommen wird um beim Forken auch dem Kindprozess zur Verfügung zu stehen. Alle exportierten Variablen können mit dem Befehl printenv oder env angezeigt werden. Wirklich alle Shellvariablen werden mit set angezeigt.

Kommandosubstitution

Bei der Kommandosubstitution wird ein Kommando mit seinem Rückgabewert ersetzt. Es existieren zwei Varianten

$(date) 
`date`

Bei der ersten Variante besteht die Möglichkeit zu schachteln:

  • cd $(echo /home/$(whoami))
  • cd `echo /home/`whoami``
  • date -u "+%X"
09:29:41
  • MOMENT=$(date -u "+%X")
  • echo $MOMENT
09:29:58
  • echo $MOMENT
09:29:58

Abgrenzen von Variablen

Folgt einem Dollarzeichen $ ein Variablenname oder eine öffnende geschweifte Klammer ${...}, so spricht man von einer Variablen- bzw. Parameterexpansion. Die geschweiften Klammern dienen zur Gruppierung und sind bei skalaren Variablen, die nicht per Parameterexpansion behandelt werden sollen, nicht notwendig.

  • SUX=eins
  • TUX=zwei
  • SUXTUX=drei
  • echo $SUX
eins
  • echo ${SUX}
eins
  • echo $SUXTUX
drei
  • echo ${SUX}TUX
einsTUX
  • echo ${SUX}${TUX}
einszwei

Weitere Mechanismen zur Parameterexpansion

Die weiteren Mechanismen zur Parameterexpansion manipulieren den Inhalt von Variablen. "FARBE" bezeichnet nachfolgend den Variablennamen und "rot" steht entweder für eine Zeichenkette oder für eine Variable, die selbst wieder eine Parameter-, Kommando, Tildeexpansion oder eine arithmetische Berechnung beinhalten kann.

  • ${FARBE:-rot}

Wenn die Variable $FARBE definiert ist, wird der Inhalt zurückgeliefert; wenn sie nicht definiert ist, wird rot zurückgeliefert

  • unset FARBE
  • echo ${FARBE:-rot}
rot
  • FARBE=gruen
  • echo ${FARBE:-rot}
gruen
  • echo $FARBE
gruen
  • ${FARBE:=rot}

Wenn die Variable $FARBE definiert ist, wird der Inhalt zurückgeliefert, wenn sie nicht definiert ist, wird rot zurückgeliefert und die Variable $FARBE wird mit dem Wert rot belegt (somit ist sie definiert).

  • unset FARBE
  • echo ${FARBE:=rot}
rot
  • echo $FARBE
rot
  • ${FARBE:?keine farbe gesetzt}

Wenn die Variable $FARBE definiert ist, wird der Inhalt zurückgeliefert, wenn sie nicht definiert ist, wird 'keine farbe' als Fehlermitteilung ausgegeben. Der Rückgabewert ist dann auch ungleich 0.

  • unset FARBE
  • echo ${FARBE:?keine farbe}
bash: FARBE: keine farbe
  • echo $?
1
  • FARBE=silber
  • echo ${FARBE:?keine farbe}
silber

  • ${FARBE:+rot}

Wenn die Variable $FARBE definiert ist, wird rot zurückgeliefert, ansonsten nichts.

  • unset FARBE
  • echo ${FARBE:+rot}
  • FARBE=gelb
  • echo ${FARBE:+rot}
rot
  • echo $FARBE
gelb

  • ${FARBE:4}

Der Inhalt der Variable wird ab der 4 Position bis zum Ende ausgegeben. Es wird ab 0 gezählt.

  • FARBE=rotweis
  • echo ${FARBE:3}
weis

  • ${FARBE:5:3}

Ab der 5 Position werden 3 Zeichen ausgegeben. Es wird ab 0 gezählt.

  • FARBE=schwarzbraun
  • echo ${FARBE:5:3}
rzb
  • ${#FARBE}

Die Anzahl Zeichen der Variable wird ausgegeben

  • FARBE=schwarzbraun
  • echo ${#FARBE}
12
  • ${FARBE#rot}

Wenn das Wort rot am Anfang der Variable steht wird der Rest der Variable ausgegeben . Wenn dies nicht so ist wird die Variable ausgegeben.

  • FARBE=rotweis
  • echo ${FARBE#rot}
weis
  • ${PROGRAM##*/}

Werden ## Kreuze angeben so wird die längstmögliche Ersetzung vorgenommen und der Rest wird ausgeben.

  • PROGRAM=/usr/bin/passwd
  • echo ${PROGRAM#*/}
usr/bin/passwd
  • echo ${PROGRAM##*/}
passwd
  • ${FARBE%weis}

Wenn das Wort rot am Ende der Variable steht wird der restliche Anfang der Variable ausgegeben. Wenn dies nicht so ist wird die Variable ausgegeben.

  • FARBE=rotweis
  • echo ${FARBE%weis}
rot
  • ${PROGRAM%%*/}

Werden %% (2 Prozentzeichen) angeben, so wird die längstmögliche Ersetzung vorgenommen und der Anfang wird ausgeben.

  • FARBE=rotweisrot
  • echo ${FARBE%o*}
rotweisr
  • echo ${FARBE%%o*}
r
  • ${FARBE/rot/blau}

Ersetzen eines Musters. Kommt in der Variable FARBE ein rot vor, wird dies durch blau ersetzt.

  • ${FARBE//rot/blau}

Ersetzen eines Musters. Kommen in der Variable FARBE mehrere rot vor, werden sie durch blau ersetzt.

  • FARBE=rotweisrot
  • echo ${FARBE/rot/blau}
blauweisrot
  • echo ${FARBE//rot/blau}
blauweisblau

Besondere Dateien

Wichtige Systemvariablen (Auswahl)

Stellungsparameter (Spezielle Variablen)

Den Stellungsparametern $1, $2, ..., $9 werden bei ihrer Definition nach ihrer Reihenfolge Werte zugewiesen. Die Definition erfolgt mit dem Kommando set', einem Skript - oder Prozeduraufruf .

Ihr Geltungsbereich ist lokal, d.h. sie gelten nur in der aktuellen bash und können nicht exportiert werden.

Belegen der Variablen mittels set

  • set der fck ist eine klasse Mannschaft
  • echo $1 $2 $3
der fck ist
  • echo $5 $6 $7
eine klasse Mannschaft
  • set unser fcs ist aber auch ok
  • echo $1 $2 $3
unser fcs ist

Belegen der Variablen durch einen Skriptaufruf

Die Variablen werden automatisch beim Skriptaufruf belegt, indem sie als Argumente dem Skript übergeben werden.

  • cat skript1
#!/bin/bash
echo "1         parameter $1"
echo "2         parameter $2"
echo "3         parameter $3"
echo "4         parameter $4"
echo "alle     parameter $*"
echo "alle     parameter $@"
echo "anzahl    parameter $#"
echo "skriptname      $0"
echo "PID des skriptes      $$"
echo "Rückgabewert letztes Kommando     $?"
  • ./skript1 blau gruen gelb rot
1            parameter blau
2            parameter gruen
3            parameter gelb
4            parameter rot
alle         parameter blau gruen gelb rot
alle         parameter blau gruen gelb rot
anzahl       parameter 4
skriptname             ./skript1
PID des skriptes       1019
Rückgabewert letztes Kommando    0

Systemparameter

Der Begriff Systemparameter bezeichnet eine Variable, die von der bash automatisch mit Werten versorgt wird. Die aktuellen Werte können vom Benutzer abgefragt werden.

Einige wichtige Systemparameter:


$$ PID des laufenden Prozesses
$! PID des letzten Hintergrundprozesses
$- Liste der für die bash gesetzten Schalter
$? Exitstatus des letzten Kommandos
$# Anzahl der Stellungsparameter
$* Liste der Stellungsparameter
$0 Aktueller Prozessname

shift-Kommando

Das Kommando bewirkt die Verschiebung aller Stellungsoperanden um eine Stelle nach links. Auf diese Weise ist nach der Anwendung des shift-Kommandos der Wert des 10ten Parameters in $9, der ursprüngliche Wert von $1 ist verloren. Die Stellenanzahl, um die verschoben wird, kann angegeben werden, z. B. bewirkt der Befehl shift 4 das Verschieben um 4 Stellen nach links.

  • set hallo ihr guten admins von der schule hier
  • echo $1 $2 $3 $4
hallo ihr guten admins
  • shift
  • echo $1 $2 $3 $4
ihr guten admins von
  • shift 3
  • echo $1 $2 $3 $4
von der schule hier

Here Dokument

Heredocs dienen zur Definition von Textabschnitten. Im Unterschied zur herkömmlichen Ausgabe per echo werden enthaltene Zeilenumbrüche, Einzüge und einige Sonderzeichen im Text bewahrt. Die Bash ermöglicht auch die Verwendung von Variablen innerhalb des Heredoc.

Der Block ab "cat<<HERE" wird bis zu "HERE" ausgegeben. Das Wort "HERE" ist beliebig. Wichtig hinter dem 2 Wort darf keine Leerzeichnen stehen.

#!/bin/bash
INT=$1
IP=$2
NM=$3
GW=$4
cat<<HERE
auto $INT
iface $INT inet static
 address $IP
 netmask $NM
 gateway $GW
HERE
  • ./interface-gen.sh eth3 192.168.24.67 255.255.255.0 192.168.24.1
auto eth3
iface eth3 inet static
 address 192.168.24.67
 netmask 255.255.255.0
 gateway 192.168.24.1

read-Kommando

Mit read wird eine Eingabezeile eingelesen und deren Inhalt Variablen zugewiesen. Die Eingabe wird anhand der Trennzeichen in einzelne Token zerlegt und der Reihe nach den Variablen zugewiesen. Stehen mehr Token zur Verfügung als Variablen, so wird die letzte Variable mit allen noch nicht zugewiesenen Token belegt; stehen weniger Token bereit, bleibt der Inhalt der überschüssigen Variablen leer:

#!/bin/bash
echo "wie heißen sie?"
read NAME VORNAME
echo "Sie heißen $VORNAME $NAME"

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


-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 	    	
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

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

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.

If.jpg

Der else-Zweig kann ausgelassen oder durch einen elif-Zweig ersetzt werden. Der elif-Zweig ist eine Besonderheit bei Verschachtelungen.

  • cat rechnertest
#!/bin/bash
if ping -c 1 -w 1 $1 > /dev/null 2>&1
then
 echo "rechner lebt"
else
 echo "rechner ist tot"
fi
  • ./rechnertest 172.20.103.1
rechner lebt
  • ./rechnertest 172.20.103.99
rechner ist tot

Variante ohne else

  • cat rechnertest.spar
#!/bin/bash
if ping -c 1 -w 1 $1 > /dev/null 2>&1
then
echo "rechner lebt"
fi
  • ./rechnertest.spar 172.20.103.1
rechner lebt
  • ./rechnertest.spar 172.20.103.99

Sonderform mit elif

  • cat el
 #!/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
  • ./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
#!/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
  • ./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
 #!/bin/bash
 while [ $# -ge 1 ]
 do
  echo $1
  echo $#
  shift
 done
  • ./proggi blau gelb gruen
blau
3
gelb
2
gruen
1

Darstellung als Struktogramm nach Nassi / Shneiderman:

While.jpg

Beispiel:

#!/bin/bash
COUNTER=$1
 while [ $COUNTER -ge 1 ]
  do
   echo $COUNTER
   COUNTER=$(($COUNTER-1))
 done
echo "BUMM BUMM"
  • ./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.

 #!/bin/bash
 while read SUX
 do
 echo $SUX
 done  <  /etc/passwd

Selbstgebautes cat

#!/bin/bash
while read ZEILE
 do
  echo $ZEILE
 done < $1

Selbstgebautes tac

#!/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

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:

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
 #!/bin/bash
 for CLUB in fck bvb schalke bmg
  do
   echo $CLUB
 done
  • ./fussball
fck
bvb
schalke
bmg

Darstellung als Struktogramm nach Nassi / Shneiderman:

For.jpg

For Schleife mit Stellungsparametern

Wird keine Liste angegeben, wird standardmäßig die Liste der Stellungsoperanden benutzt. Folgende Anweisungen sind äquivalent

#!/bin/bash
for LAUF in $*
 do
  echo $LAUF
 done

Kurzform :

for LAUF 
 do
  echo $LAUF
 done

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.

 
#!/bin/bash
for LAUF in *
do
 echo $LAUF
done

Hier die Variante mit einem grossen K

#!/bin/bash
for LAUF in K*
do
 echo $LAUF
done

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
 #!/bin/bash
 for ((I=1;I<5;I++))
 do
 echo $I
 done
  • ./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.

#!/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
  • ./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.


#!/bin/bash
select auswahl in Punkt1 Punkt2 Punkt3 Punkt4
do
   echo "Ihre Auswahl war : $auswahl"
done
#!/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



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.

#!/bin/bash 
while true
 do
  test -f /tmp/sux && break  
  echo "unn weiter"
  sleep 3
 done
 echo  "und tschuess"

Funktionen

bash funktion

Signalbehandlung

Signale bei der Programmierung der bash

Es existieren verschiedene Möglichkeiten, auf welchem Wege Signale gesendet werden können:

  1. von aussen:
    1. Benutzer (< DEL >, < CTRL >|, etc.)
    2. Prozesse (kill, alarm)
  2. von innen:
    1. 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:

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
#!/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

Bemerkung: Die Signalbehandlung selbst wird nicht an Kindprozesse weitervererbt. Das Ignorieren von Signalen hingegen wird weitervererbt.

Weitere Möglichkeiten der Bash-Shell

Alias-Namen

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

#!/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

Gleichzeitiges Lesen aus Datei und Standardeingabe

#!/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

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

#!/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
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.


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:

\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:

%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

#!/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

Links

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.
if [ -f "$ FILE"]
  • um leere Zeichenfolgen oder Dateinamen mit Leerzeichen richtig zu behandeln. Mit "[[" sind die Anführungszeichen unnötig:
if [[ -f $ FILE ]]
  • 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
if ["$ ANSWER" = y -o "$ ANSWER" = yes]
  • Mit [[ können Sie dies als schreiben
if [[ $ ANSWER = ~ ^ y (es)? ]]
  • 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