Bourne Again Shell: Unterschied zwischen den Versionen

Aus Mikiwiki
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: Die <b>Bourne-Again-Shell / Bash</b> ist die konsequente Weiterentwicklung der Bourne-Shell auf GNU/Linux-Systemen, zusätzlich sind viele Fähigkeiten der ...)
 
 
(39 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
Die <b>Bourne-Again-[[Shell]] / Bash</b> ist die konsequente Weiterentwicklung der [[Bourne-Shell]] auf GNU/[[Linux]]-Systemen, zusätzlich sind viele Fähigkeiten der [[Korn-Shell]] und der [[C-Shell]] implementiert. Sie ist die Standard-Shell der meisten Linux-Systeme, ist aber auch auf anderen Unix-Systemen und sogar für OS/2 oder [[Microsoft Windows]] verfügbar.
Die [[Shell]] <b>Bourne-Again Shell / Bash</b> ist die konsequente Weiterentwicklung der [[Bourne-Shell]] auf GNU/[[Linux]]-Systemen, zusätzlich sind viele Fähigkeiten der [[Korn-Shell]] und der [[C-Shell]] implementiert. Sie ist die Standard-Shell der meisten Linux-Systeme, ist aber auch auf anderen Unix-Systemen und sogar für OS/2 oder [[Microsoft Windows]] verfügbar.


Unter Linux gibt es keine Bourne-Shell mehr, der Standardeintrag "/bin/sh" ist ein Link auf "/bin/bash". Da die Bourne-Again-Shell eine Obermenge der Bourne-Shell ist, wird keine separate Bourne-Shell benötigt. Zum Feststellen der installierten Version der Bourne-Again-Shell dienen folgende Befehle.
Unter Linux gibt es keine Bourne-Shell mehr, der Standardeintrag "/bin/sh" ist ein Link auf "/bin/bash". Da die Bourne-Again-Shell eine Obermenge der Bourne-Shell ist, wird keine separate Bourne-Shell benötigt. Zum Feststellen der installierten Version der Bourne-Again-Shell dienen folgende Befehle.


  $ echo $BASH_VERSION
  $ <b>echo $BASH_VERSION</b>
  $ bash --version
  $ <b>bash --version</b>


Es gibt einige Befehle, die nicht als eigenständige Programme im System, sondern als Bestandteil der Shell bereits von der Bash selbst ausgeführt werden (bash builtin commands). Neben "man bash" steht mit "man bashbuiltins" ein zusätzliches Handbuch zur Verfügung.
Es gibt einige Befehle, die nicht als eigenständige Programme im System, sondern als Bestandteil der Shell bereits von der Bash selbst ausgeführt werden (bash builtin commands). Neben "man bash" steht mit "man bashbuiltins" ein zusätzliches Handbuch zur Verfügung.
Zeile 14: Zeile 14:
  $ <b>[[help]]</b>
  $ <b>[[help]]</b>


=== GNU bash, version 3.2.13(1)-release (i486-pc-linux-gnu) ===
=== GNU bash, Version 5.0.3(1)-release (x86_64-pc-linux-gnu) ===
 
GNU bash, Version 5.0.3(1)-release (x86_64-pc-linux-gnu)
 
Die Shell Kommandos sind intern definiert. Mit "help" kann eine Liste angesehen werden. Durch "help Name" wird eine Beschreibung der Funktion "Name" angezeigt. Die Dokumentation ist mit "info bash" einsehbar. Detaillierte  Beschreibungen der Shellkommandos sind mit "man -k" oder "info" abrufbar.
 
Ein Stern (*) neben dem Namen kennzeichnet deaktivierte Kommandos.


  JOB_SPEC [&]
  Jobbezeichnung [&]
  (( expression ))
  (( Ausdruck ))
  . filename [arguments]
  . Dateiname [Argumente]
  :
  :
  [ arg... ]
  [ Argument... ]
  <nowiki>[[ expression ]]</nowiki>
  <nowiki>[[ Ausdruck ]]</nowiki>
  [[alias]] [-p] [name[=value] ... ]
  [[alias]] [-p] [Name[=Wert] ... ]
  [[bg]] [job_spec ...]
  [[bg]] [Jobbezeichnung ...]
  [[bind]] [-lpvsPVS] [-m keymap] [-f fi
  [[bind]] [-lpsvPSVX] [-m Tastaturtabelle] [-f Dateiname] [-q Name] [-u Name] [-r Tastenfolge] [-x Tastenfolge:Shell Ko>
  [[break]] [n]
  [[break]] [n]
  [[builtin]] [shell-builtin [arg ...]]
  [[builtin]] [Shellkommando [Argument ...]]
  [[caller]] [EXPR]
  [[caller]] [Ausdruck]
  [[case]] WORD in [PATTERN [| PATTERN].
  [[case]] Wort in [Muster [| Muster]...) Kommandos ;;]... esac
  [[cd]] [-L|-P] [dir]
  [[cd]] [-L|[-P [-e]] [-@]] [Verzeichnis]
  [[command]] [-pVv] command [arg ...]
  [[command]] [-pVv] Kommando [Argument ...]
  [[compgen]] [-abcdefgjksuv] [-o option
  [[compgen]] [-abcdefgjksuv] [-o Option] [-A Aktion] [-G Suchmuster] [-W Wortliste] [-F Funktion] [-C Kommando] [-X Fil>
  [[complete]] [-abcdefgjksuv] [-pr] [-o
  [[complete]] [-abcdefgjksuv] [-pr] [-DE] [-o Option] [-A Aktion]          [-G Suchmuster] [-W Wortliste]  [-F Funktion>
[[compopt]] [-o|+o Option] [-DEI] [Name ...]
  [[continue]] [n]
  [[continue]] [n]
  [[declare]] [-afFirtx] [-p] [name[=val
[[coproc]] [Name] Kommando [Umleitungen]
  [[declare]] [-aAfFgilrntux] [-p] [Name[=Wert] ...]
  [[dirs]] [-clpv] [+N] [-N]
  [[dirs]] [-clpv] [+N] [-N]
  [[disown]] [-h] [-ar] [jobspec ...]
  [[disown]] [-h] [-ar] [Jobbezeichnung ... | pid ...]
  [[echo]] [-neE] [arg ...]
  [[echo]] [-neE] [Argument ...]
  [[enable]] [-pnds] [-a] [-f filename]
  [[enable]] [-a] [-dnps] [-f Dateiname] [Name ...]
  [[eval]] [arg ...]
  [[eval]] [Argument ...]
  [[exec]] [-cl] [-a name] file [redirec
  [[exec]] [-cl] [-a Name] [Kommando [Argumente ...]] [Umleitung ...]
  [[exit [n]
  [[exit]] [n]
  [[export]] [-nf] [name[=value] ...] or
  [[export]] [-fn] [Name[=Wert] ...] oder export -p
  [[false]]
  [[false]]
  [[fc]] [-e ename] [-nlr] [first] [last
  [[fc]] [-e Editor] [-lnr] [Anfang] [Ende] oder fc -s [Muster=Ersetzung] [Kommando]
  [[fg]] [job_spec]
  [[fg]] [Jobbezeichnung]
  [[for]] NAME [in WORDS ... ;] do COMMA
  [[for]] Name [in Wortliste ... ] ; do Kommandos; done
  [[for]] (( exp1; exp2; exp3 )); do COM
  [[for]] (( Ausdr1; Ausdr2; Ausdr3 )); do Kommandos; done
  [[function]] NAME { COMMANDS ; } or NA
  [[function]] Name { Kommandos ; } oder Name () { Kommandos ; }
  [[getopts]] optstring name [arg]
  [[getopts]] Optionen Variable [Argumente]
  [[hash]] [-lr] [-p pathname] [-dt] [na
  [[hash]] [-lr] [-p Pfadname] [-dt] [Name ...]
  [[help]] [-s] [pattern ...]
  [[help]] [-dms] [Muster ...]
  [[history]] [-c] [-d offset] [n] or hi
  [[history]] [-c] [-d Offset] [n] oder history -anrw [Dateiname] oder history -ps Argument [Argument...]
  [[if]] COMMANDS; then COMMANDS; [ elif
  [[if]] Kommandos; then Kommandos; [ elif Kommandos; then Kommandos; ]... [ else Kommandos; ] fi
  [[jobs]] [-lnprs] [jobspec ...] or job
  [[jobs]] [-lnprs] [Jobbez. ...] or jobs -x Kommando [Arg]
  [[kill]] [-s sigspec | -n signum | -si
  [[kill]] [-s Signalname | -n Signalnummer | -Signalname] pid | jobspec ... oder kill -l [Signalname]
  [[let]] arg [arg ...]
  [[let]] Argument [Argument ...]
  [[local]] name[=value] ...
  [[local]] [Option] Name[=Wert] ...
  [[logout]]
  [[logout]] [n]
  [[popd]] [+N | -N] [-n]
[[mapfile]] [-d Begrenzer] [-n Anzahl] [-O Quelle] [-s Anzahl] [-t] [-u fd] [-C Callback] [-c Menge] [Feldvariable]
  [[printf]] [-v var] format [arguments]
  [[popd]] [-n] [+N | -N]
  [[pushd]] [dir | +N | -N] [-n]
  [[printf]] [-v var] Format [Argumente]
  [[pushd]] [-n] [+N | -N | Verzeichnis]
  [[pwd]] [-LP]
  [[pwd]] [-LP]
  [[read]] [-ers] [-u fd] [-t timeout] [
  [[read]] [-ers] [-a Feld] [-d Begrenzer] [-i Text] [-n Zeichenanzahl] [-N Zeichenanzahl] [-p Prompt] [-t Zeitlimit] [>
  [[readonly]] [-af] [name[=value] ...]
[[readarray]] [-d Begrenzer] [-n Anzahl] [-O Quelle] [-s Anzahl] [-t]          [-u fd] [-C Callback] [-c Menge] [Fel>
  [[readonly]] [-aAf] [Name[=Wert] ...] oder readonly -p
  [[return]] [n]
  [[return]] [n]
  [[select]] NAME [in WORDS ... ;] do CO
  [[select]] Name [in Wortliste ... ;] do Kommandos; done
  [[set]] [--abefhkmnptuvxBCHP] [-o opti
  [[set]] [-abefhkmnptuvxBCHP] [-o Option] [--] [Argument ...]
  [[shift]] [n]
  [[shift]] [n]
  [[shopt]] [-pqsu] [-o long-option] opt
  [[shopt]] [-pqsu] [-o] [Optionsname ...]
  [[source]] filename [arguments]
  [[source]] Dateiname [Argumente]
  [[suspend]] [-f]
  [[suspend]] [-f]
  [[test]] [expr]
  [[test]] [Ausdruck]
  [[time]] [-p] PIPELINE
  [[time]] [-p] Pipeline
  [[times]]
  [[times]]
  [[trap]] [-lp] [arg signal_spec ...]
  [[trap]] [-lp] [[Argument] Signalbezeichnung ...]
  [[true]]
  [[true]]
  [[type]] [-afptP] name [name ...]
  [[type]] [-afptP] Name [Name ...]
  [[typeset]] [-afFirtx] [-p] name[=valu
  [[typeset]] [-aAfFgilnrtux] [-p] Name[=Wert] ...
  [[ulimit]] [-SHacdfilmnpqstuvx] [limit
  [[ulimit]] [-SHabcdefiklmnpqrstuvxPT] [Grenze]
  [[umask]] [-p] [-S] [mode]
  [[umask]] [-p] [-S] [Modus]
  [[unalias]] [-a] name [name ...]
  [[unalias]] [-a] Name [Name ...]
  [[unset]] [-f] [-v] [name ...]
  [[unset]] [-f] [-v] [-n] [NAME ...]
  [[until]] COMMANDS; do COMMANDS; done
  [[until]] Kommandos; do Kommandos; done
  [[variable]]s - Some variable names an
  [[variables]] - Namen und Bedeutung einiger Shell Variablen
  [[wait]] [n]
  [[wait]] [-fn] [id ...]
  [[while]] COMMANDS; do COMMANDS; done
  [[while]] Kommandos; do Kommandos; done
  { COMMANDS ; }
  { Kommandos ; }
 
=== GNU bash, version 3.2.13(1)-release (i486-pc-linux-gnu) ===
 
[[/GNU bash, version 3.2.13(1)-release (i486-pc-linux-gnu)|GNU bash, version 3.2.13(1)-release (i486-pc-linux-gnu)]]


== Variablen ==
== Variablen ==
Zeile 105: Zeile 119:
* "$HOME/.login" ([[csh]]-Login)
* "$HOME/.login" ([[csh]]-Login)
* "$HOME/.profile" ([[sh]]- und [[ksh]]-Login)
* "$HOME/.profile" ([[sh]]- und [[ksh]]-Login)
Siehe dazu auch den Abschnitt "[[#Startskripte|Startskripte]]".
=== Klammern ===
* https://dev.to/rpalo/bash-brackets-quick-reference-4eh6


=== Umgebungsvariablen ===
=== Umgebungsvariablen ===
Zeile 111: Zeile 131:


{| class=wikitable width=100%
{| class=wikitable width=100%
! width=10% | Umgebungsvariable !! Beschreibung
! Umgebungsvariable !! Beschreibung
|-
|-
| <tt>BASH_VERSION</tt>
| <tt>BASH_VERSION</tt>
Zeile 204: Zeile 224:
|-
|-
| <tt>PPID</tt>
| <tt>PPID</tt>
| PID des Elternprozesses der Shell.
| [[Prozessnummer]] des Elternprozesses der Shell.
|-
|-
| <tt>PRINTER</tt>
| <tt>PRINTER</tt>
Zeile 275: Zeile 295:


{| class=wikitable width=100%
{| class=wikitable width=100%
| width=10% | <tt>$0</tt>
! width=10% | Parameter !! Beschreibung
|-
| <tt>$0</tt>
| Name des Shellskripts
| Name des Shellskripts
|-
|-
| <tt>$1</tt>
| <tt>$1</tt>
| Wert des 1. Parameters
| Wert des 1. Positionsparameters
|-
|-
| <tt>$2</tt>
| <tt>$2</tt>
| Wert des 2. Parameters, usw.
| Wert des 2. Positionsparameters
|-
|-
| <tt>$*</tt>
| <tt>$*</tt>
| Werte aller angegebenen Parameter
| Werte aller angegebenen Positionsparameter von 1 an
|-
|-
| <tt>$@</tt>
| <tt>$@</tt>
| Alle Parameter
| Alle Positionsparameter von 1 an
|-
|-
| <tt>$#</tt>
| <tt>$#</tt>
| Anzahl der Parameter
| Anzahl der Positionsparameter
|-
|-
| <tt>$?</tt>
| <tt>$?</tt>
| Exit-Status des letzten Befehls
| Rückgabewert (Exit-Status) des letzten Befehls
|-
| <tt>$-</tt>
| Die Optionsflags (von set oder aus der Befehlszeile)
|-
|-
| <tt>$$</tt>
| <tt>$$</tt>
| Prozessnummer des Shellskripts
| [[Prozessnummer]] des Shellskripts
|-
| <tt>$!</tt>
| [[Prozessnummer]] des zuletzt im Hintergrund aufgerufenen Befehls
|-
| <tt>$_</tt>
| Letztes Argument des zuletzt ausgeführten Befehls
|}
|}


Zeile 315: Zeile 346:
echo "Der 3. Parameter lautet: $3"
echo "Der 3. Parameter lautet: $3"
echo "Dies sind alle angegebenen Parameter: $*"
echo "Dies sind alle angegebenen Parameter: $*"
echo "Die PID des Shellskripts lautet: $$"
echo "Die Prozessnummer des Shellskripts lautet: $$"
</pre>
</pre>


Zeile 336: Zeile 367:
== Tastaturfunktionen ==
== Tastaturfunktionen ==


Normalerweise kann mit den Pfeiltasten durch die bisherigen Befehle navigiert werden. Für mächtigere Befehle werden die Tastenkombinationen von "emacs" verwendet. Wie bei der Korn-Shell können mit "set -o vi" die Tastenkombinationen des "vi" aktiviert werden. Ebenfalls sind die History-Funktionen der C-Shell implementiert:
Normalerweise kann mit den Pfeiltasten durch die bisherigen Befehle navigiert werden. Für mächtigere Befehle werden die Tastenkombinationen von "emacs" verwendet. Wie bei der Korn-Shell können mit "set -o vi" die Tastenkombinationen des "vi" aktiviert werden. Ebenfalls sind die [[Shell-History]]-Funktionen der C-Shell implementiert:


{| class=wikitable width=100%
{| class=wikitable width=100%
! width=10% | Tasten-<br>kombination |
! width=10% | Tasten-<br>kombination !! Beschreibung
|-
|-
| <tt>TAB </tt>
| <tt>TAB </tt>
Zeile 369: Zeile 400:
|}
|}


== Startup-Skripte ==
== Startskripte ==
 
Wird die Bash als <b>Login-Shell</b> gestartet, so soll die Benutzerumgebung initialisiert werden. Dabei definiert die Bash einige Variablen und Aliases sowie über [[umask]] die standardmässigen Zugriffsrechte für neu erstellte Dateien. Bei der Anmeldung eines Benutzers wird normalerweise eine solche Login-Shell aufgerufen, die nacheinander folgende Dateien abarbeitet, falls diese vorhanden sind:


Bei Start der Bourne-Again-Shell als <b>Login-Shell</b> werden folgende Dateien abgearbeitet (falls sie vorhanden sind):
# "/etc/profile" (gilt für alle Benutzer und sorgt für eine gleiche Startumgebung)
# "/etc/profile" (gilt für alle Benutzer und sorgt für eine gleiche Startumgebung)
# nacheinander wird nach "~/.bash_profile" bzw. "~/.bash_login" bzw. "~/.profile" (Benutzereinstellungen) gesucht. Wird eine dieser Dateien gefunden, so wird nicht weiter nach einer anderen dieser Dateien gesucht.
# nacheinander wird folgenden Dateien gesucht - wird eine von ihnen gefunden, so wird nicht weiter nach einer anderen dieser Dateien gesucht.
* "~/.bash_profile"
* "~/.bash_login"
* "~/.profile" (Benutzereinstellungen)
 
Wird die Bash als <b>Non-Login-Shell</b> (auch: interaktive Shell) ausgeführt, so initialisiert diese ihre Systemumgebung nicht selbst, sondern geht davon aus, dass der übergeordnete Prozess bereits eine Systemumgebung geschaffen hat und diese vererbt. Als Non-Login-Shells gelten beispielsweise alle Shells, die aus einer anderen Shell heraus aufgerufen werden - dazu gehören auch X-Terminals oder andere Konsolenprogramme unter der grafischen Benutzeroberfläche. Ebenso kann man durch Aufruf des Befehls "bash" in eine Non-Login-Shell gelangen. Startskripte für Non-Login-Shells werden hauptsächlich angelegt, weil die Shell keine Aliases vererbt.
 
Die Bash Version 4 arbeitet dabei nacheinander folgende Dateien ab, sofern sie vorhanden sind.


Wird die Bourne-Again-Shell als <b>Non-Login-Shell</b> ausgeführt, werden folgende Dateien abgearbeitet (falls sie vorhanden sind). Als solche interaktive Shell gelten z. B. alle Shells, die aus einer anderen Shell heruas aufgerufen werden - dazu gehören auch X-Terminals oder andere Konsolenprogramme unter der grafischen Benutzeroberfläche.
# "/etc/bash.bashrc" (systemweite Datei) oder "/etc/bashrc"
# "/etc/bash.bashrc" (systemweite Datei)
# "~/.bashrc" (benutzerbezogene Datei)
# "~/.bashrc" (benutzerbezogene Datei)
Ältere Versionen der Bash kümmern sich dagegen nur um die Datei "~/.bashrc", die dann ihrerseits auf die Inhalte der Datei "/etc/bashrc" zugreift.


Um also immer dieselbe Umgebung zur Verfügung zu haben, wird die Datei "~/.bash_profile" erstellt, in der sich eine Reihe nützlicher Befehle befinden - der erste davon ist "source $HOME/.bashrc", mit dem die
Um also immer dieselbe Umgebung zur Verfügung zu haben, wird die Datei "~/.bash_profile" erstellt, in der sich eine Reihe nützlicher Befehle befinden - der erste davon ist "source $HOME/.bashrc", mit dem die
Umgebungsvariablen und die komplette Konfiguration gesetzt wird. Grundsätzlich sollten die Befehle wie folgt verteilt werden:
Umgebungsvariablen und die komplette Konfiguration gesetzt wird. Grundsätzlich sollten die Befehle wie folgt verteilt werden:
* die Datei ".bash_profile" enthält alles, was nur bei Einloggen in einen Computer ausgeführt werden soll.
* die Datei ".bash_profile" enthält alles, was nur bei Anmelden an einen Rechner ausgeführt werden soll.
* die Datei ".bashrc" enthält alles, was in jedem beliebigen Terminalfenster gesetzt werden soll - also wohl der Grossteil der Konfiguration. An ihrem Ende befindet sich z. B. der Aufruf der Datei ".alias", in der typischerweise alle alias-Definitionen gesammelt sind.
* die Datei ".bashrc" enthält alles, was in jedem beliebigen Terminalfenster gesetzt werden soll - also wohl der Grossteil der Konfiguration. An ihrem Ende befindet sich z. B. der Aufruf der Datei ".alias", in der typischerweise alle alias-Definitionen gesammelt sind.


Beim <b>Ausloggen</b> wird ausserdem die die Datei "~/.bash_logout" ausgeführt.
Beim <b>Ausloggen</b> wird ausserdem die die Datei "~/.bash_logout" ausgeführt.
Mit welcher Art Bash der Benutzer aktuell arbeitet, kann mit dem Befehl "echo $0" überprüft werden. Im folgenden Beispiel ("bash") handelt es sich um eine Login-Shell. Eine andere Ausgabe weist auf eine Non-Login-Shell hin.
$ <b>echo $0</b>
bash


== Prompt ==
== Prompt ==
Zeile 421: Zeile 466:
| <tt>\]</tt> || Abschluss der Eingabe von Steuerzeichen.
| <tt>\]</tt> || Abschluss der Eingabe von Steuerzeichen.
|}
|}
== Rechnen ==
Unter Verwendung einer besonderen Syntax kann die Bash mit ganzen Zahlen und Variablen [[rechnen]] - mit Nachkommastellen kann die Bash allerdings nicht umgehen. Die im folgenden gezeigte Syntax ist dabei erst ab der Bash 2.0 gültig. Zu den möglichen Operatoren gehören die folgenden:
{| class=wiki
| <tt>+</tt> || Addition
|-
| <tt>-</tt> || Subtraktion
|-
| <tt>*</tt> || Multiplikation
|-
| <tt>/</tt> || Division
|-
| <tt>**</tt> || Exponential-Operator
|-
| <tt>%</tt> || Modulo-Operator, der den Rest bei der ganzzahligen Division berechnet.
|}
Rechnen mit ganzen Zahlen.
$ <b>echo $((1+1))</b>
2
Rechnen mit Variablen.
$ <b>a=4; b=5; echo $((a+b))</b>
9
Ausgabe des Wertes für 2 hoch 16.
$ <b>echo $((2**16))</b>
65536
Ausgabe des Modulowertes der Division von 5 durch 3. Das Ergebnis lautet 2, da bei der Division von 5 durch 3 der Rest 2 bleibt.
$ <b>echo $((5%3))</b>
2
Im Fall der Division zeigt sich, dass die Bash tatsächlich nur mit ganzen Zahlen rechnen kann.
$ <b>echo $((1/3))</b>
0
== FAQ ==
=== Geschweifte Klammern ===
Geschweifte Klammern dienen beispielsweise zum Bilden einer Sequenz.
$ <b>echo {0..10}</b>
0 1 2 3 4 5 6 7 8 9 10
$ <b>echo {10..0}</b>
10 9 8 7 6 5 4 3 2 1 0
Ausgabe nur jeden zweiten Zeichens einer Sequenz.
$ <b>echo {10..0..2}</b>
10 8 6 4 2 0
$ <b>echo {z..a..2}</b>
z x v t r p n l j h f d b
Kombination zweier Sequenzen.
$ <b>echo {a..f}{a..f}</b>
aa ab ac ad ae af ba bb bc bd be bf ca cb cc cd ce cf da db dc dd de df ea eb ec ed ee ef fa fb fc fd fe ff
Arrays werden in der Bash in runden Klammern geschrieben, wobei die einzelnen Elemente jeweils durch ein Leerzeichen getrennt werden. Einzelne Elemente des Arrays können über den Index inerhalb von eckigen Klammern angesprochen werden - hier etwa das vierte Element (da Arrays immer mit Index 0 beginnen):
$ <b>month=("Jan" "Feb" "Mär" "Apr" "Mai" "Jun" "Jul" "Aug" "Sep" "Okt" "Nov" "Dez")</b>
$ <b>echo ${month[3]}</b>
Apr
Das Array "letter_combos" enthält alle zwei-Buchstaben-Kombinationen des gesamten Alphabets.
$ <b>letter_combos=({a..z}{a..z})</b>
$ <b>echo ${letter_combos[3]}</b>
ad
Das Array "dec2bin" enthält alle Binärzahlen für ein 8-bit-Register in aufsteigender Reihenfolge, beginnend mit 00000000, 00000001, 00000010 usw., bis 11111111 erreicht wird. Dies kann verwendet werden, um einen 8-bit Dezimal-zu-Binär-Konverter zu erstellen.
$ <b>dec2bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})</b>
Anzeige der Zeichenfolge 25 im Binärformat.
$ <b>echo ${dec2bin[25]}</b>
00011001
==== Parametererweiterung ====
Im Fall
$ <b>echo ${month[3]}</b>
werden die geschweiften Klammern nicht als Teil einer Sequenzerstellung verwendet, sondern um eine Parametererweiterung zu erzeugen. Die Parametererweiterung nimmt die Variable oder den Ausdruck in den geschweiften Klammern und erweitert sie auf das, was sie darstellt. Im aktuellen Fall heisst das zuvor definierte Array "month"; Index 3 dieses Arrays zeigt auf "Apr".
Mithilfe der Parametererweiterung kann der aus der Variable gelesene Inhalt auch verändert werden. Im folgenden beispielw erden die letzten zwei Vorkommen des Buchstabens "g" abgeschnitten.
* <code>${...}</code> weist die Shell an, alles zu erweitern, was sich darin befindet
* a ist die Variable
* % teilt der Shell mit, dass etwas vom Ende der erweiterten Variablen abgeschnitten werden soll
* "gg" ist die abzuschneidende Zeichenfolge
$ <b>a="Zu langgg"</b>
$ <b>echo ${a%gg}</b>
Zu lang
Mit dem Befehl "convert" (aus der Sammlung Imagemagick) können beispielsweise JPEG-Bilder in PNG-Bilder konvertiert werden. Der folgende Befehl nimmt die JPEG-Datei "bild.jpg" und erstellt eine Kopie unter dem Namen "bild.png" im PNG-Format. Im zweiten Beispiel wird die Dateinamenserweiterung "jpg" abgeschnitten und stattdessen "png" hinzugefügt.
$ <b>convert bild.jpg bild.png</b>
oder
$ <b>i=bild.jpg</b>
$ <b>convert $i ${i%jpg}png</b>
Dies ist besonders nützlich, wenn in einem Verzeichnis hunderte von Dateien umgewandelt werden sollen:
$ <b>for i in *.jpg
    do
    convert $i ${i%jpg}png
    done</b>
Um einen Teil vom Beginn einer Variable wegzuschneiden, wird das Zeichen "#" verwendet.
$ <b>a="Hallo Welt!"</b>
$ <b>echo Auf Wiedersehen${a#Hallo}</b>
Auf Wiedersehen Welt!
==== Ausgabegruppierung ====
Geschweifte Klammern können auch verwendet werden, um die Ausgabe mehrerer Befehle in einen grossen Blob zu gruppieren. Folgender Befehl führt alle Befehle aus, schreibt jedoch nur die Ausgabe des letzten ls-Befehls in die Datei "PNGs.txt".
$ <b>echo "I found all these PNGs:"; find . -iname "*.png"; echo "Within this bunch of files:"; ls > PNGs.txt</b>
Der folgende Befehl schreibt die Ausgaben aller Befehl innerhalb der geschweiften Klammern (mit nachfolgendem bzw. vorangestelltem Leerzeichen) in die Datei "PNGs.txt". Hinter dem letzten Befehl muss ebenfalls ein Strichpunkt stehen.
$ <b>{ echo "I found all these PNGs:"; find . -iname "*.png"; echo "Within this bunch of files:"; ls; } > PNGs.txt</b>
=== Eckige Klammern ===
* https://www.linux.com/training-tutorials/using-square-brackets-bash-part-1/
* https://www.linux.com/training-tutorials/using-square-brackets-bash-part-2/
Die Verwendung von Platzhaltern, um alle Ergebnisse zu erhalten, die einem bestimmten Muster entsprechen, wird auch als "Globbing" bezeichnet. Beispielsweise zum Auflisten aller Dateien, welche auf ".jpg" enden - das Sternchen bedeutet dabei null oder mehr beliebige Zeichen:
$ <b>ls *.jpg</b>
Das Zeichen "?" ist ein weiterer Globbing-Platzhalter und bedeutet genau ein beliebiges Zeichen.
Anzeige von Dateien mit Namen wie "dark", "darkly", "duck" oder "ducky":
$ <b>ls d*k*</b>
Anzeige von Dateien mit Namen wie "ducky" (aber nicht "dark", "darkly" oder "duck").
$ <b>ls d*k?</b>
Eckige Klammern werden beim Globbing für Zeichensätze verwendet. In einem Testverzeichnis können mit folgendem Befehl Testdateien mit Namen von "file000" bis "file099" erstellt werden:
$ <b>touch file0{0..9}{0..9}</b>
Auflistung der Dateien, welche mit file07 oder file08 beginnen, worauf genau ein weiteres Zeichen folgt.
$ <b>ls Datei0[78]?</b>
Auflistung der Dateien "file022", "file027", "file028", "file052", "file057", "file058", "file082", "file087" und "file088".
$ <b>ls file0[259][278]</b>
Globbing (und eckige Klammern für Mengen) können ausser mit dem befehl "ls" auch mit jedem anderen befehl zum Auflisten, Entfernen, Verschieben oder Kopieren von Dateien verwendet werden.
Beispielsweise sollen Duplikate der Dateien "file010" bis "file029" erstellt und die Kopien "archive010", "archive011" usw. genannt werden. Folgendes ist nicht möglich, da Globbing dem Abgleich mit vorhandenen Dateien und Verzeichnissen - die "archive..."-Dateien existieren aber gar noch nicht.
$ <b>cp file0[12]? archive0[12]?</b>
Auch folgender Befehl ist nicht möglich, da mit dem Befehl "cp" nicht viele Dateien in viele neue Dateien kopiert werden können.
$ <b>cp file0[12]? archive0[1..2][0..9]</b>
Das Kopieren vieler Dateien funktioniert nur, wenn sie in in Verzeichnis kopiert werden. Folgendes würde also funktionieren, aber die Dateien hätten im neuen Verzeichnis "archive" immer noch den bisherigen Namen.
$ <b>mkdir archive</b>
$ <b>cp file0[12]? archive</b>
Übungshalber kann folgendes versucht werden. Dabei wird durch "#Hello" dieser Teil der Variable "myvar" entfernt.
$ <b>myvar="Hello World"</b>
$ <b>echo Goodbye Cruel ${myvar#Hello}</b>
Goodbye Cruel World
Diese Funktion kann zusammen mit den Globbing-Befehlen zum Erstellen der gewünschten archive-Duplikate erstellt werden - es werden also die Dateien "archive010" bis "archive029" erstellt.
* Die erste Zeile teilt dem Bash-Interpreter mit, dass alle Dateien durchlaufen werden sollen, welche die Zeichenfolge file0 gefolgt von den Ziffern 1 oder 2 und dann einem weiteren beliebigen Zeichen.
* Die zweite Zeile do gibt an, dass es sich beim folgenden um die Anweisung oder Liste von Anweisungen handelt, welche der Interpreter durchlaufen soll.
* In der dritten Zeile erfolgt das eigentliche Kopieren, wobei der Inhalt der Schleifenvariablen "i" zweimal verwendet wird: Zuerst direkt als erster Parameter des Befehls "cp", danach wird dem Inhalt die Zeichenfolge "archive" angehängt, während gleichzeitig der Bestandteil "file" weggeschnitten wird. Falls "i" beispielsweise "file019" enthält wird davor "archive" geschrieben, "file" weggeschnitten und es bleibt "archive019".
$ <b>for i in file0[12]?;
    do
    cp $i archive${i#file};
    done</b>
Eckige Klammern können ausserdem auch als Befehl wie der Befehl [[test]] verwendet werden.
Für das Vorkommen doppelter eckiger Klammern (z. B. <code>[[ ... ]]</code>) siehe
* https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Bash-Conditional-Expressions
=== Top 10 der Bash-Befehle ===
Die folgende Befehlsfolge zeigt, welche Bash-Befehle ich seit dem 17. Oktober auf meinem neuen Ubuntu 7.10-System am häufigsten ausgeführt habe:
$ <b>history | awk '{print $2}' | sort | uniq -c | sort -nr | head</b>
    238 ls
    203 cd
    41 sudo
    40 mplayer
    26 more
    21 rm
    21 mv
    19 qmv
    17 history
    10 echo
Und was sieht man daraus? Dass ich öfter mal als Superuser arbeite (sudo), dass ich Filme guck und Musik höre (mplayer), dass ich öfter mehrere Dateien gleichzeitig umbenenne (qmv) und dass ich ein wenig mit obiger Zeile rumgespielt habe (history)...
Natürlich ist die ausgegebene Liste erklärungsbedürftig:
1. Die Ausgabeliste berücksichtigt nur die in der "history" noch vorhandenen Einträge. Die Anzahl der dort zu speichernden Zeilen lässt sich aber über die Variable "$HISTSIZE" einstellen - am besten direkt in der Datei "/etc/profile" mit folgendem Befehl (für 5'000 Zeilen):
export HISTSIZE=5000
2. In der Ausgabe werden immer nur die ersten Befehle berücksichtigt - durch Pipes miteinander verknüpfte Folgebefehle werden also nicht mitgezählt. Der folgende Befehl zählt aber auch die durch Pipes miteinander verknüpften Befehle:
$ <b>history | sed 's/|/\nx /' | awk '{print $2}' | sort | uniq -c | sort -nr | head</b>
=== Zähler ===
Mehrere Möglichkeiten:
var=$((var+1))
((var=var+1))
((var+=1))
((var++))
let "var=var+1"
let "var+=1"
let "var++"


== Weblinks ==
== Weblinks ==


* [http://www.linux-user.de/ausgabe/2000/08/088-bash/bash-history.html Die Bash, das unbekannte Wesen] (Linux-User.de) - Bash-History
{{Weblinks}}
* [http://www.ss64.com/bash/ An A-Z Index of the Linux BASH command line]
{{url_dewikipedia|Bash#Die_Bourne-Again-Shell|Die Bourne-Again-Shell}}
{{dewi|Bash#Die_Bourne-Again-Shell|Die Bourne-Again-Shell}}
{{url|DE|Linux User|ger|http://www.linux-user.de/ausgabe/2000/08/088-bash/bash-history.html|Die Bash, das unbekannte Wesen|Bash-History}}
{{url|GB|Simon Sheppard|eng|http://www.ss64.com/bash/|An A-Z Index of the Linux Bash command line}}
{{Fuss}}




{{cat|Bash}}
{{cat|Bourne Again Shell}}
{{cat|Rechnen}}
{{cat|Shell}}
{{cat|Shell}}
{{cat|Skriptsprache}}

Aktuelle Version vom 6. Mai 2024, 11:05 Uhr

Die Shell Bourne-Again Shell / Bash ist die konsequente Weiterentwicklung der Bourne-Shell auf GNU/Linux-Systemen, zusätzlich sind viele Fähigkeiten der Korn-Shell und der C-Shell implementiert. Sie ist die Standard-Shell der meisten Linux-Systeme, ist aber auch auf anderen Unix-Systemen und sogar für OS/2 oder Microsoft Windows verfügbar.

Unter Linux gibt es keine Bourne-Shell mehr, der Standardeintrag "/bin/sh" ist ein Link auf "/bin/bash". Da die Bourne-Again-Shell eine Obermenge der Bourne-Shell ist, wird keine separate Bourne-Shell benötigt. Zum Feststellen der installierten Version der Bourne-Again-Shell dienen folgende Befehle.

$ echo $BASH_VERSION
$ bash --version

Es gibt einige Befehle, die nicht als eigenständige Programme im System, sondern als Bestandteil der Shell bereits von der Bash selbst ausgeführt werden (bash builtin commands). Neben "man bash" steht mit "man bashbuiltins" ein zusätzliches Handbuch zur Verfügung.

Befehlssatz

Ausgabe des eingebauten Befehlssatzes.

$ help

GNU bash, Version 5.0.3(1)-release (x86_64-pc-linux-gnu)

GNU bash, Version 5.0.3(1)-release (x86_64-pc-linux-gnu)

Die Shell Kommandos sind intern definiert. Mit "help" kann eine Liste angesehen werden. Durch "help Name" wird eine Beschreibung der Funktion "Name" angezeigt. Die Dokumentation ist mit "info bash" einsehbar. Detaillierte Beschreibungen der Shellkommandos sind mit "man -k" oder "info" abrufbar.

Ein Stern (*) neben dem Namen kennzeichnet deaktivierte Kommandos.

Jobbezeichnung [&]
(( Ausdruck ))
. Dateiname [Argumente]
:
[ Argument... ]
[[ Ausdruck ]]
alias [-p] [Name[=Wert] ... ]
bg [Jobbezeichnung ...]
bind [-lpsvPSVX] [-m Tastaturtabelle] [-f Dateiname] [-q Name] [-u Name] [-r Tastenfolge] [-x Tastenfolge:Shell Ko>
break [n]
builtin [Shellkommando [Argument ...]]
caller [Ausdruck]
case Wort in [Muster [| Muster]...) Kommandos ;;]... esac
cd [-L|[-P [-e]] [-@]] [Verzeichnis]
command [-pVv] Kommando [Argument ...]
compgen [-abcdefgjksuv] [-o Option] [-A Aktion] [-G Suchmuster] [-W Wortliste] [-F Funktion] [-C Kommando] [-X Fil>
complete [-abcdefgjksuv] [-pr] [-DE] [-o Option] [-A Aktion]          [-G Suchmuster] [-W Wortliste]  [-F Funktion>
compopt [-o|+o Option] [-DEI] [Name ...]
continue [n]
coproc [Name] Kommando [Umleitungen]
declare [-aAfFgilrntux] [-p] [Name[=Wert] ...]
dirs [-clpv] [+N] [-N]
disown [-h] [-ar] [Jobbezeichnung ... | pid ...]
echo [-neE] [Argument ...]
enable [-a] [-dnps] [-f Dateiname] [Name ...]
eval [Argument ...]
exec [-cl] [-a Name] [Kommando [Argumente ...]] [Umleitung ...]
exit [n]
export [-fn] [Name[=Wert] ...] oder export -p
false
fc [-e Editor] [-lnr] [Anfang] [Ende] oder fc -s [Muster=Ersetzung] [Kommando]
fg [Jobbezeichnung]
for Name [in Wortliste ... ] ; do Kommandos; done
for (( Ausdr1; Ausdr2; Ausdr3 )); do Kommandos; done
function Name { Kommandos ; } oder Name () { Kommandos ; }
getopts Optionen Variable [Argumente]
hash [-lr] [-p Pfadname] [-dt] [Name ...]
help [-dms] [Muster ...]
history [-c] [-d Offset] [n] oder history -anrw [Dateiname] oder history -ps Argument [Argument...]
if Kommandos; then Kommandos; [ elif Kommandos; then Kommandos; ]... [ else Kommandos; ] fi
jobs [-lnprs] [Jobbez. ...] or jobs -x Kommando [Arg]
kill [-s Signalname | -n Signalnummer | -Signalname] pid | jobspec ... oder kill -l [Signalname]
let Argument [Argument ...]
local [Option] Name[=Wert] ...
logout [n]
mapfile [-d Begrenzer] [-n Anzahl] [-O Quelle] [-s Anzahl] [-t] [-u fd] [-C Callback] [-c Menge] [Feldvariable]
popd [-n] [+N | -N]
printf [-v var] Format [Argumente]
pushd [-n] [+N | -N | Verzeichnis]
pwd [-LP]
read [-ers] [-a Feld] [-d Begrenzer] [-i Text] [-n Zeichenanzahl] [-N Zeichenanzahl] [-p Prompt] [-t Zeitlimit] [>
readarray [-d Begrenzer] [-n Anzahl] [-O Quelle] [-s Anzahl] [-t]           [-u fd] [-C Callback] [-c Menge] [Fel>
readonly [-aAf] [Name[=Wert] ...] oder readonly -p
return [n]
select Name [in Wortliste ... ;] do Kommandos; done
set [-abefhkmnptuvxBCHP] [-o Option] [--] [Argument ...]
shift [n]
shopt [-pqsu] [-o] [Optionsname ...]
source Dateiname [Argumente]
suspend [-f]
test [Ausdruck]
time [-p] Pipeline
times
trap [-lp] [[Argument] Signalbezeichnung ...]
true
type [-afptP] Name [Name ...]
typeset [-aAfFgilnrtux] [-p] Name[=Wert] ...
ulimit [-SHabcdefiklmnpqrstuvxPT] [Grenze]
umask [-p] [-S] [Modus]
unalias [-a] Name [Name ...]
unset [-f] [-v] [-n] [NAME ...]
until Kommandos; do Kommandos; done
variables - Namen und Bedeutung einiger Shell Variablen
wait [-fn] [id ...]
while Kommandos; do Kommandos; done
{ Kommandos ; }

GNU bash, version 3.2.13(1)-release (i486-pc-linux-gnu)

GNU bash, version 3.2.13(1)-release (i486-pc-linux-gnu)

Variablen

set zeigt alle Variablen und die dazugehörigen Werte.

Anzeige des aktuellen Shell-Zustands. Gezeigt wird, welche Bash-internen Werkzeuge standardmässig aktiviert sind.

$ set -o

Anzeige einer Liste der durch die Bash reservierten Variablennamen.

$ help variables

Einige sitzungsweit gültige Shellvariablen lädt der Befehlsinterpreter bei seiner Initialisierung aus der Systemdatei "/etc/profile" sowie aus folgenden anwenderspezifischen Dateien:

  • "$HOME/.bash_profile" (bash-Login)
  • "$HOME/.bashrc"
  • "$HOME/.login" (csh-Login)
  • "$HOME/.profile" (sh- und ksh-Login)

Siehe dazu auch den Abschnitt "Startskripte".

Klammern

Umgebungsvariablen

Darüberhinaus werden viele Umgebungsvariablen automatisch gesetzt, die meisten davon dürfen durch den Benutzer geändert werden und auf alle Variablen darf lesend zugegriffen werden. Die vollständige Liste aller Umgebungsvariablen der Bash findet sich in der zugehörigen man page.

Umgebungsvariable Beschreibung
BASH_VERSION Versionsinformation der aktuellen Bash.
CDPATH Eine durch Doppelpunkte getrennte Liste von Verzeichnissen, die durchsucht werden, wenn das Argument für cd nicht im aktuellen Verzeichnis gefunden wird.
EDITOR Standard-Texteditor. Standardmässig wird vi verwendet.
ENV Name der Datei, die die Voreinstellungen der Korn-Shell enthält. Normalerweise "$HOME/.kshrc".
EUID Die effektive Benutzerkennung (Nummer).
EXINIT Voreinstellungen für die Editoren ex bzw. vi, z. B. EXINIT="set number showmode"
GLOBIGNORE Eine durch Doppelpunkte getrennte Liste von Dateinamenmustern, die bei der Dateinamenexpansion ignoriert werden sollen.
HISTFILE Name der Datei, in der die Befehlshistory gespeichert wird. Vorgabewert ist "~/.bash_history".
HISTFILESIZE Maximale Anzahl Zeilen, welche die Datei $HISTFILE enthalten kann.
HISTIGNORE Eine durch Doppelpunkte getrennte Liste von Mustern zum Entscheiden, welche Befehle in der history-Liste gespeichert werden sollen.
HISTSIZE Maximale Anzahl History-Zeilen, auf die eine laufende Shell zugreifen kann.
HOME Der absolute Pfadname zum login-Verzeichnis des aktuellen Benutzers (Standardverzeichnis für den Befehl cd), so wie es in der Datei "/etc/passwd" hinterlegt wurde. Die Tilde "~" kann sowohl für Benutzereingaben als auch für Shellausgaben als Abkürzung für "$HOME" verwendet werden.
HOST / HOSTNAME Rechnername des aktuellen Rechners.
HOSTTYPE Prozessortyp, unter dem die aktuelle bash läuft. Beispiel: "i386"
$IFS Interner Feldtrenner. Die Shell-Befehlszeilen werden anhand dieser Variable in Elemente zerlegt. Alle angegebenen Zeichen können als Trenner von Wörtern benutzt werden. Standardmässig ist die Variable mit den sogenannten whitespaces (Leerzeichen und Tabulator) und newline (Zeilenvorschub) vorbelegt:

IFS=$' \t\n'

IGNOREEOF Kontrolliert das Verhalten der shell beim Erhalt eines EOF-Zeichens als einzige Eingabe. Die dem EOF-Zeichen zugewiesene Tastenkombination (meist "CTRL d") kann genau wie exit zum Beenden der aktuellen shell verwendet werden. Wenn gesetzt, dann entspricht der Wert der Anzahl EOF-Zeichen, die auf einer Zeile nacheinander angezeigt werden können, bevor die shell sich beendet (Standard sind 10). Wenn nicht gesetzt, bezeichnet EOF das Ende der Eingabe.
LANG Sprache, in der Systemmeldungen erfolgen sollen (soweit vorhanden). In dieser Sprache erfolgen die Programmausgaben, Datumsformat usw., sofern keine der "LC_"-Variablen (sieh unten) gesetzt sind. Eine Liste der definierten Sprachvariablen zeigt der Befehl locale.

LANG=de_DE@euro

LC_ALL Ländereinstellung, z. B. "C" oder "de". Diese Variable setzt "LANG" und alle anderen "LC_"-Variablen ausser Kraft.
LC_MESSAGES Sprache für Programm- und Fehlermeldungen.
LC_TIME Zeitformat.
LOGNAME Login-Name des Benutzers.
MACHTYPE Eine Zeichenfolge, die das System beschreibt, unter dem die aktuelle bash läuft. Beispiel: "i686-suse-linux"
MAIL Pfad zur Mailbox des aktuellen Benutzers (eingehende Post).
MAILCHECK Die Häufigkeit (in Sekunden), mit der bash nach neuer mail sieht.
MAILPATH Eine durch Doppelpunkte getrennte Liste von Dateien, die bash nach neuer mail durchsucht.
MANPATH Suchpfad zu den installierten man-Pages.
OSTYPE Die Version von Unix, auf der die aktuelle bash läuft.
PATH Der absolute Suchpfad für ausführbare Programme: eine durch Doppelpunkte getrennte Liste von Verzeichnissen, die bei der Suche nach Befehlen von links nach rechts durchsucht werden, bis ein Verzeichnis mit dem entsprechenden Binärprogramm gefunden ist.

Aus Sicherheitsgründen sollte das aktuelle Verzeichnis in der Variable "$PATH" für den Benutzer "root" nicht vorkommen. Unter SuSE kann dies in der Datei "/etc/sysconfig/suseconfig" durch Setzen der Variable "CWD_IN_ROOT_PATH=no" erreicht werden. Beispiel:
PATH=/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:.:/opt/kde3/bin:/opt/kde2/bin:/usr/lib/java/bin
Beispiel einer Ergänzung:
$ PATH=$PATH:$HOME/sc

PPID Prozessnummer des Elternprozesses der Shell.
PRINTER Bezeichnung des Standarddruckers.
PROMPT_COMMAND Ein Befehl, der vor dem Ausgeben des primären prompts ausgeführt werden soll.
PS1 Die den primären prompt (Standardeingabeprompt) beschreibende Zeichenfolge.
  • \h - Hostname bis zum ersten Punkt
  • \t - die Uhrzeit im 24-Stunden-Format
  • \u - Benutzername des aktuellen Benutzers
  • \w - aktuelles Verzeichnis

Beispiel: PS1=$'\\u@\\h:\\w> '
Beispiel einer Neubesetzung, um stets das aktuelle Verzeichnis anzuzeigen (nur Korn-Shell):
$ PS1="`$PWD`"
oder
$ PS1="\$PWD : "

Standardbelegung unter SUSE Linux Enterprise Server 10
PS1="\u@\h:\w> "

Standardbelegung unter Ubuntu 7.04:
PS1="${debian_chroot:+($debian_chroot)}\u@\h:\w\$ "

PS2 Die den sekundären prompt beschreibende Zeichenfolge, der nach Eingabe unvollständiger Befehle oder beim Fehlen schliessender Klammern erscheint, also z. B. beim Umbruch einer unvollständigen Befehlszeile mit RETURN. Standardzeichen ist ">".
PS3 Verwendet die "select"-Kontrollstruktur der Bash.
PS4 Erscheint beim Debugging eines Skripts vor jeder Zeile.
PWD Der volle Pfadname zum aktuellen Verzeichnis.
SHELL Voller Pfadname der aktuellen Shell, z. B. "/bin/bash".
SHELLOPTS Eine durch Doppelpunkte getrennte Liste von eingeschalteten Shelloptionen.
TERM Der Name des aktuellen Terminaltyps der Dialogstation, z. B. "xterm" oder "vt220". Wichtig für viele bildschirmorientierte Programme wie die grafische Oberfläche, vi, more, usw.
TIMEFORMAT Das Ausgabeformat für Zeitangaben, das vom Befehl "time" verwendet wird.
TZ Angaben zur Zeitzone, z. B. "CET" oder "MET". Diese Variable wird z. B. für die automatische Berechnung der Ortszeiten bei mail verwendet.
UID Benutzerkennung gemäss der Datei "/etc/password", z. B. "500".
VISUAL Ist diese Variable belegt, kann die Befehlszeile editiert werden.
auto_resume Non-null means a command word appearing on a line by itself is first looked for in the list of currently stopped jobs. If found there, that job is foregrounded. A value of `exact' means that the command word must exactly match a command in the list of stopped jobs. A value of 'substring' means that the command word must match a substring of the job. Any other value means that the command must be a prefix of a stopped job.
histchars Characters controlling history expansion and quick substitution. The first character is the history substitution character, usually '!'. The second is the 'quick substitution' character, usually '^'. The third is the 'history comment' character, usually '#'.

Positionsparameter

Innerhalb eines Shellskripts stehen weitere Shellvariablen zur Verfügung. Die Shell analysiert den Befehlsaufruf und erkennt, getrennt durch ein oder mehrere Leerzeichen, folgende Teile:

Parameter Beschreibung
$0 Name des Shellskripts
$1 Wert des 1. Positionsparameters
$2 Wert des 2. Positionsparameters
$* Werte aller angegebenen Positionsparameter von 1 an
$@ Alle Positionsparameter von 1 an
$# Anzahl der Positionsparameter
$? Rückgabewert (Exit-Status) des letzten Befehls
$- Die Optionsflags (von set oder aus der Befehlszeile)
$$ Prozessnummer des Shellskripts
$! Prozessnummer des zuletzt im Hintergrund aufgerufenen Befehls
$_ Letztes Argument des zuletzt ausgeführten Befehls

Beispielskript:

#!/bin/sh
#
# Name: posi
# Beschreibung: Ausgabe der einzelnen Positionsparameter
# Parameter: Beliebig
#-------------------------------------------------------
#
echo "Der Name des Shellskripts lautet: $0"
echo "Es wurden $# Parameter angegeben."
echo "Der 1. Parameter lautet: $1"
echo "Der 2. Parameter lautet: $2"
echo "Der 3. Parameter lautet: $3"
echo "Dies sind alle angegebenen Parameter: $*"
echo "Die Prozessnummer des Shellskripts lautet: $$"

Terminaleinstellungen

LINES Eine Zahl, die die Höhe des Anzeigebildschirms in Zeilen angibt.
COLUMNS Eine Zahl, die die Breite des Anzeigebildschirms in Zeichen angibt.
DISPLAY Wird vom X Window System verwendet, wo Programme die auf dem aktuellen Terminal ausgeführt werden, gezeichnet werden sollen. Die Variable besteht aus einem Rechnernamen (bzw. dem Namen des X-Terminals), einem Doppelpunkt und einer Nummer des Bildschirms, auf dem eine Anwendung ausgeführt werden soll (diese Nummer besteht aus zwei durch einen Punkt getrennten Zahlen), z. B. "meister:0.0".
TERM Art des verwendeten Displays. Die Fähigkeiten der verschiedenen terminals sind in der Datei "/etc/termcap" beschrieben. Zu den bekanntesten gehören vt100, vt102 und vt220.

Tastaturfunktionen

Normalerweise kann mit den Pfeiltasten durch die bisherigen Befehle navigiert werden. Für mächtigere Befehle werden die Tastenkombinationen von "emacs" verwendet. Wie bei der Korn-Shell können mit "set -o vi" die Tastenkombinationen des "vi" aktiviert werden. Ebenfalls sind die Shell-History-Funktionen der C-Shell implementiert:

Tasten-
kombination
Beschreibung
TAB vervollständigt Umgebungsvariablen sowie Verzeichnis- und Dateinamen, die über den Pfad der Variable "PATH" erreichbar sind.
CTRL+A bewegt den Cursor an den Anfang der Zeile
CTRL+E bewegt den Cursor ans Ende der Zeile
CTRL+D
DEL
löscht die Zeichen unter dem Cursor
Backspace löscht ein Zeichen nach links
CTRL+K löscht von der Cursorposition bis ans Ende der Zeile
CTRL+U löscht von der Cursorposition bis an den Anfang der Zeile
CTRL+R für inkrementelles Suchen in der History. Am erscheinenden prompt kann ein Bestandteil des gesuchten Befehls eingegeben werden. "Ctrl R" zum Weitersuchen in der History. Nach Eingabe von "Esc" kann der gefundene Befehl vor dem Ausführen noch verändert werden. "Return" zum Abschicken des Befehls.
CTRL+L löscht den Inhalt des Terminal-Fensters (wie clear)

Startskripte

Wird die Bash als Login-Shell gestartet, so soll die Benutzerumgebung initialisiert werden. Dabei definiert die Bash einige Variablen und Aliases sowie über umask die standardmässigen Zugriffsrechte für neu erstellte Dateien. Bei der Anmeldung eines Benutzers wird normalerweise eine solche Login-Shell aufgerufen, die nacheinander folgende Dateien abarbeitet, falls diese vorhanden sind:

  1. "/etc/profile" (gilt für alle Benutzer und sorgt für eine gleiche Startumgebung)
  2. nacheinander wird folgenden Dateien gesucht - wird eine von ihnen gefunden, so wird nicht weiter nach einer anderen dieser Dateien gesucht.
  • "~/.bash_profile"
  • "~/.bash_login"
  • "~/.profile" (Benutzereinstellungen)

Wird die Bash als Non-Login-Shell (auch: interaktive Shell) ausgeführt, so initialisiert diese ihre Systemumgebung nicht selbst, sondern geht davon aus, dass der übergeordnete Prozess bereits eine Systemumgebung geschaffen hat und diese vererbt. Als Non-Login-Shells gelten beispielsweise alle Shells, die aus einer anderen Shell heraus aufgerufen werden - dazu gehören auch X-Terminals oder andere Konsolenprogramme unter der grafischen Benutzeroberfläche. Ebenso kann man durch Aufruf des Befehls "bash" in eine Non-Login-Shell gelangen. Startskripte für Non-Login-Shells werden hauptsächlich angelegt, weil die Shell keine Aliases vererbt.

Die Bash Version 4 arbeitet dabei nacheinander folgende Dateien ab, sofern sie vorhanden sind.

  1. "/etc/bash.bashrc" (systemweite Datei) oder "/etc/bashrc"
  2. "~/.bashrc" (benutzerbezogene Datei)

Ältere Versionen der Bash kümmern sich dagegen nur um die Datei "~/.bashrc", die dann ihrerseits auf die Inhalte der Datei "/etc/bashrc" zugreift.

Um also immer dieselbe Umgebung zur Verfügung zu haben, wird die Datei "~/.bash_profile" erstellt, in der sich eine Reihe nützlicher Befehle befinden - der erste davon ist "source $HOME/.bashrc", mit dem die Umgebungsvariablen und die komplette Konfiguration gesetzt wird. Grundsätzlich sollten die Befehle wie folgt verteilt werden:

  • die Datei ".bash_profile" enthält alles, was nur bei Anmelden an einen Rechner ausgeführt werden soll.
  • die Datei ".bashrc" enthält alles, was in jedem beliebigen Terminalfenster gesetzt werden soll - also wohl der Grossteil der Konfiguration. An ihrem Ende befindet sich z. B. der Aufruf der Datei ".alias", in der typischerweise alle alias-Definitionen gesammelt sind.

Beim Ausloggen wird ausserdem die die Datei "~/.bash_logout" ausgeführt.

Mit welcher Art Bash der Benutzer aktuell arbeitet, kann mit dem Befehl "echo $0" überprüft werden. Im folgenden Beispiel ("bash") handelt es sich um eine Login-Shell. Eine andere Ausgabe weist auf eine Non-Login-Shell hin.

$ echo $0
bash

Prompt

Das Aussehen des Prompts als Eingabeaufforderung nach dem Ausführen eines Befehls wird durch die Umgebungsvariable "$PS1" festgelegt. Diese wird am besten in der Konfigurationsdatei "~/.bashrc" gesetzt.

Der Prompt kann mit Hilfe besonderer Escape-Sequenzen gestaltet werden, u. a.

Zeichen Beschreibung
\e Das Zeichen für "Escape" ("^[").
\h Hostname des Rechners in Kurzform (bis zum ersten Punkt).
\n Zeilenvorschub
\r Wagenrücklauf
\u Benutzername
\w Das aktuelle Arbeitsverzeichnis mit voller Pfadangabe.
\W Das aktuelle Arbeitsverzeichnis, auf das gegenwärtige Verzeichnis beschränkt.
\! Reihenfolge des Befehls in der Bash-History, z. B. "89" für den 89. ausgeführten Befehl.
\$ Anzeige eines Dollarzeichens ("$") für alle Benutzer, die nicht die UID 0 (root) haben, andernfalls ein Rautezeichen ("#").
\nnn Dreistellige Oktalzahl "nnn", mit der jedes beliebige ASCII-Zeichen dargestellt werden kann, z. B. "\033" für "Escape".
\\ Ein umgekehrter Schrägstrich ("\").
\[ Einleitung für nachfolgende Steuerzeichen, etwa ANSI-Escape- oder ANSI-Steuersequenzen für den Cursor.
\] Abschluss der Eingabe von Steuerzeichen.

Rechnen

Unter Verwendung einer besonderen Syntax kann die Bash mit ganzen Zahlen und Variablen rechnen - mit Nachkommastellen kann die Bash allerdings nicht umgehen. Die im folgenden gezeigte Syntax ist dabei erst ab der Bash 2.0 gültig. Zu den möglichen Operatoren gehören die folgenden:

+ Addition
- Subtraktion
* Multiplikation
/ Division
** Exponential-Operator
% Modulo-Operator, der den Rest bei der ganzzahligen Division berechnet.

Rechnen mit ganzen Zahlen.

$ echo $((1+1))
2

Rechnen mit Variablen.

$ a=4; b=5; echo $((a+b))
9

Ausgabe des Wertes für 2 hoch 16.

$ echo $((2**16))
65536

Ausgabe des Modulowertes der Division von 5 durch 3. Das Ergebnis lautet 2, da bei der Division von 5 durch 3 der Rest 2 bleibt.

$ echo $((5%3))
2

Im Fall der Division zeigt sich, dass die Bash tatsächlich nur mit ganzen Zahlen rechnen kann.

$ echo $((1/3))
0

FAQ

Geschweifte Klammern

Geschweifte Klammern dienen beispielsweise zum Bilden einer Sequenz.

$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10
$ echo {10..0}
10 9 8 7 6 5 4 3 2 1 0

Ausgabe nur jeden zweiten Zeichens einer Sequenz.

$ echo {10..0..2}
10 8 6 4 2 0
$ echo {z..a..2}
z x v t r p n l j h f d b

Kombination zweier Sequenzen.

$ echo {a..f}{a..f}
aa ab ac ad ae af ba bb bc bd be bf ca cb cc cd ce cf da db dc dd de df ea eb ec ed ee ef fa fb fc fd fe ff

Arrays werden in der Bash in runden Klammern geschrieben, wobei die einzelnen Elemente jeweils durch ein Leerzeichen getrennt werden. Einzelne Elemente des Arrays können über den Index inerhalb von eckigen Klammern angesprochen werden - hier etwa das vierte Element (da Arrays immer mit Index 0 beginnen):

$ month=("Jan" "Feb" "Mär" "Apr" "Mai" "Jun" "Jul" "Aug" "Sep" "Okt" "Nov" "Dez")
$ echo ${month[3]}
Apr

Das Array "letter_combos" enthält alle zwei-Buchstaben-Kombinationen des gesamten Alphabets.

$ letter_combos=({a..z}{a..z})
$ echo ${letter_combos[3]}
ad

Das Array "dec2bin" enthält alle Binärzahlen für ein 8-bit-Register in aufsteigender Reihenfolge, beginnend mit 00000000, 00000001, 00000010 usw., bis 11111111 erreicht wird. Dies kann verwendet werden, um einen 8-bit Dezimal-zu-Binär-Konverter zu erstellen.

$ dec2bin=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1})

Anzeige der Zeichenfolge 25 im Binärformat.

$ echo ${dec2bin[25]}
00011001

Parametererweiterung

Im Fall

$ echo ${month[3]}

werden die geschweiften Klammern nicht als Teil einer Sequenzerstellung verwendet, sondern um eine Parametererweiterung zu erzeugen. Die Parametererweiterung nimmt die Variable oder den Ausdruck in den geschweiften Klammern und erweitert sie auf das, was sie darstellt. Im aktuellen Fall heisst das zuvor definierte Array "month"; Index 3 dieses Arrays zeigt auf "Apr".

Mithilfe der Parametererweiterung kann der aus der Variable gelesene Inhalt auch verändert werden. Im folgenden beispielw erden die letzten zwei Vorkommen des Buchstabens "g" abgeschnitten.

  • ${...} weist die Shell an, alles zu erweitern, was sich darin befindet
  • a ist die Variable
  • % teilt der Shell mit, dass etwas vom Ende der erweiterten Variablen abgeschnitten werden soll
  • "gg" ist die abzuschneidende Zeichenfolge
$ a="Zu langgg"
$ echo ${a%gg}
Zu lang

Mit dem Befehl "convert" (aus der Sammlung Imagemagick) können beispielsweise JPEG-Bilder in PNG-Bilder konvertiert werden. Der folgende Befehl nimmt die JPEG-Datei "bild.jpg" und erstellt eine Kopie unter dem Namen "bild.png" im PNG-Format. Im zweiten Beispiel wird die Dateinamenserweiterung "jpg" abgeschnitten und stattdessen "png" hinzugefügt.

$ convert bild.jpg bild.png

oder

$ i=bild.jpg
$ convert $i ${i%jpg}png

Dies ist besonders nützlich, wenn in einem Verzeichnis hunderte von Dateien umgewandelt werden sollen:

$ for i in *.jpg
    do
    convert $i ${i%jpg}png
    done

Um einen Teil vom Beginn einer Variable wegzuschneiden, wird das Zeichen "#" verwendet.

$ a="Hallo Welt!"
$ echo Auf Wiedersehen${a#Hallo}
Auf Wiedersehen Welt!

Ausgabegruppierung

Geschweifte Klammern können auch verwendet werden, um die Ausgabe mehrerer Befehle in einen grossen Blob zu gruppieren. Folgender Befehl führt alle Befehle aus, schreibt jedoch nur die Ausgabe des letzten ls-Befehls in die Datei "PNGs.txt".

$ echo "I found all these PNGs:"; find . -iname "*.png"; echo "Within this bunch of files:"; ls > PNGs.txt

Der folgende Befehl schreibt die Ausgaben aller Befehl innerhalb der geschweiften Klammern (mit nachfolgendem bzw. vorangestelltem Leerzeichen) in die Datei "PNGs.txt". Hinter dem letzten Befehl muss ebenfalls ein Strichpunkt stehen.

$ { echo "I found all these PNGs:"; find . -iname "*.png"; echo "Within this bunch of files:"; ls; } > PNGs.txt

Eckige Klammern

Die Verwendung von Platzhaltern, um alle Ergebnisse zu erhalten, die einem bestimmten Muster entsprechen, wird auch als "Globbing" bezeichnet. Beispielsweise zum Auflisten aller Dateien, welche auf ".jpg" enden - das Sternchen bedeutet dabei null oder mehr beliebige Zeichen:

$ ls *.jpg

Das Zeichen "?" ist ein weiterer Globbing-Platzhalter und bedeutet genau ein beliebiges Zeichen.

Anzeige von Dateien mit Namen wie "dark", "darkly", "duck" oder "ducky":

$ ls d*k*

Anzeige von Dateien mit Namen wie "ducky" (aber nicht "dark", "darkly" oder "duck").

$ ls d*k?

Eckige Klammern werden beim Globbing für Zeichensätze verwendet. In einem Testverzeichnis können mit folgendem Befehl Testdateien mit Namen von "file000" bis "file099" erstellt werden:

$ touch file0{0..9}{0..9}

Auflistung der Dateien, welche mit file07 oder file08 beginnen, worauf genau ein weiteres Zeichen folgt.

$ ls Datei0[78]?

Auflistung der Dateien "file022", "file027", "file028", "file052", "file057", "file058", "file082", "file087" und "file088".

$ ls file0[259][278]

Globbing (und eckige Klammern für Mengen) können ausser mit dem befehl "ls" auch mit jedem anderen befehl zum Auflisten, Entfernen, Verschieben oder Kopieren von Dateien verwendet werden.

Beispielsweise sollen Duplikate der Dateien "file010" bis "file029" erstellt und die Kopien "archive010", "archive011" usw. genannt werden. Folgendes ist nicht möglich, da Globbing dem Abgleich mit vorhandenen Dateien und Verzeichnissen - die "archive..."-Dateien existieren aber gar noch nicht.

$ cp file0[12]? archive0[12]?

Auch folgender Befehl ist nicht möglich, da mit dem Befehl "cp" nicht viele Dateien in viele neue Dateien kopiert werden können.

$ cp file0[12]? archive0[1..2][0..9]

Das Kopieren vieler Dateien funktioniert nur, wenn sie in in Verzeichnis kopiert werden. Folgendes würde also funktionieren, aber die Dateien hätten im neuen Verzeichnis "archive" immer noch den bisherigen Namen.

$ mkdir archive
$ cp file0[12]? archive

Übungshalber kann folgendes versucht werden. Dabei wird durch "#Hello" dieser Teil der Variable "myvar" entfernt.

$ myvar="Hello World"
$ echo Goodbye Cruel ${myvar#Hello}
Goodbye Cruel World

Diese Funktion kann zusammen mit den Globbing-Befehlen zum Erstellen der gewünschten archive-Duplikate erstellt werden - es werden also die Dateien "archive010" bis "archive029" erstellt.

  • Die erste Zeile teilt dem Bash-Interpreter mit, dass alle Dateien durchlaufen werden sollen, welche die Zeichenfolge file0 gefolgt von den Ziffern 1 oder 2 und dann einem weiteren beliebigen Zeichen.
  • Die zweite Zeile do gibt an, dass es sich beim folgenden um die Anweisung oder Liste von Anweisungen handelt, welche der Interpreter durchlaufen soll.
  • In der dritten Zeile erfolgt das eigentliche Kopieren, wobei der Inhalt der Schleifenvariablen "i" zweimal verwendet wird: Zuerst direkt als erster Parameter des Befehls "cp", danach wird dem Inhalt die Zeichenfolge "archive" angehängt, während gleichzeitig der Bestandteil "file" weggeschnitten wird. Falls "i" beispielsweise "file019" enthält wird davor "archive" geschrieben, "file" weggeschnitten und es bleibt "archive019".
$ for i in file0[12]?;
    do
    cp $i archive${i#file};
    done

Eckige Klammern können ausserdem auch als Befehl wie der Befehl test verwendet werden.

Für das Vorkommen doppelter eckiger Klammern (z. B. ... ) siehe

Top 10 der Bash-Befehle

Die folgende Befehlsfolge zeigt, welche Bash-Befehle ich seit dem 17. Oktober auf meinem neuen Ubuntu 7.10-System am häufigsten ausgeführt habe:

$ history | awk '{print $2}' | sort | uniq -c | sort -nr | head
   238 ls
   203 cd
    41 sudo
    40 mplayer
    26 more
    21 rm
    21 mv
    19 qmv
    17 history
    10 echo

Und was sieht man daraus? Dass ich öfter mal als Superuser arbeite (sudo), dass ich Filme guck und Musik höre (mplayer), dass ich öfter mehrere Dateien gleichzeitig umbenenne (qmv) und dass ich ein wenig mit obiger Zeile rumgespielt habe (history)...

Natürlich ist die ausgegebene Liste erklärungsbedürftig:

1. Die Ausgabeliste berücksichtigt nur die in der "history" noch vorhandenen Einträge. Die Anzahl der dort zu speichernden Zeilen lässt sich aber über die Variable "$HISTSIZE" einstellen - am besten direkt in der Datei "/etc/profile" mit folgendem Befehl (für 5'000 Zeilen):

export HISTSIZE=5000

2. In der Ausgabe werden immer nur die ersten Befehle berücksichtigt - durch Pipes miteinander verknüpfte Folgebefehle werden also nicht mitgezählt. Der folgende Befehl zählt aber auch die durch Pipes miteinander verknüpften Befehle:

$ history | sed 's/|/\nx /' | awk '{print $2}' | sort | uniq -c | sort -nr | head

Zähler

Mehrere Möglichkeiten:

var=$((var+1))
((var=var+1))
((var+=1))
((var++))
let "var=var+1"
let "var+=1"
let "var++"

Weblinks

Herausgeber Sprache Webseitentitel Anmerkungen
Wikipedia ger Die Bourne-Again-Shellwbm Enzyklopädischer Artikel
Linux User ger Die Bash, das unbekannte Wesenwbm Bash-History
Simon Sheppard eng An A-Z Index of the Linux Bash command linewbm