Bash (Shell)
Bash | |
---|---|
260px Beispiel einer bash-Sitzung | |
Basisdaten | |
Entwickler | Chet Ramey |
Aktuelle Version | 4.3 (1. Oktober 2014) |
Betriebssystem | Unix, u. a. OS X, Linux |
Programmiersprache | C |
Kategorie | Kommandozeileninterpreter |
Lizenz | GPL (Freie Software) |
Deutschsprachig | Ja |
tiswww.case.edu |
Bash (für Bourne-again shell) ist eine freie Unix-Shell und Teil des GNU-Projekts. Sie ist heute auf vielen unixoiden Systemen die Standard-Shell.
Der Name ist absichtlich mehrdeutig und bedeutet unter anderem „wiedergeborene (born again) Shell“, „wieder einmal (eine) Bourne-Shell“ oder auch aus dem Englischen to bash (schlagen, kritisieren, schlecht machen) bzw. umgangssprachlich „Party/Fete“.
Inhaltsverzeichnis
Geschichte
bash wurde 1987 von Brian Fox geschrieben und 1990 von Chet Ramey übernommen. Version 3 erschien am 27. Juli 2004. Version 4 erschien am 20. Februar 2009 und brachte einige Neuerungen mit sich. Darunter sind eine neue Ausgabeumleitung, assoziative Arrays und eine neue Wildcard (**).<ref>heise.de</ref><ref>tiswww.case.edu</ref>
Funktionalität
Vergleich mit anderen Shells
Die Shell ist weitgehend kompatibel zur Bourne-Shell (sh) und beherrscht zusätzlich sowohl die meisten Funktionen der Korn Shell (ksh) als auch Teile der C-Shell (csh)-Syntax, wie zum Beispiel die „Command-History“, die $RANDOM-Variable und die POSIX-Form der Command-Substitution $(...) wurden übernommen. Auch wurde sie um Funktionen wie z. B. der Ganzzahlarithmetik ohne die Ausführung externer Prozesse und Vereinfachung der I/O-Umleitungen erweitert. Bash bietet anhand ihrer Konfigurationsdatei ~/.bashrc außerdem die Möglichkeit, eigene Einstellungen, wie eine individuelle Promptgestaltung, sitzungsübergreifend zu sichern.
Subshell
Eine Subshell ist ein Shellprozess, der von einer Shell erzeugt wurde. Programme, die durch Eingabe eines Kommandos in eine Shell zur Ausführung gebracht werden, werden betriebssystembedingt in einer Subshell gestartet: Bevor die Shell ein Programm als Kindprozess starten kann, muss sie einen Shellprozess erzeugen. Bei der Ausführung eines Programms aus der grafischen Benutzeroberfläche heraus ist jedoch keine Shell oder Subshell involviert.
Subshells werden automatisch bei der Verwendung einer Reihe von Bashfeatures erzeugt. Beispielsweise werden alle Befehle einer Pipeline in einer eigenen Subshell ausgeführt. Shells in grafischen Oberflächen, wie kterm oder gnome-terminal, sind keine Subshells, da ihr Elternprozess keine Shell ist.
Login-Shell
Wird die bash mit dem Parameter '-' bzw. '--login' gestartet, wie es beim Login auf der Konsole der Fall ist, nennt man sie Login-Shell. Somit können offensichtlich auch Subshells Login-Shells sein. Das Verhalten einer Login-Shell weicht von dem einer Nicht-Login-Shell ab. So liest eine Login-Shell andere Konfigurationsdateien (/etc/profile, ~/.bash_profile, ~/.bash_login, ~/.profile) als eine Nicht-Login-Shell (/etc/bash.bashrc, ~/.bashrc) ein. Außerdem werden Login-Shells mit dem Befehl 'logout' verlassen, und können nicht mit dem Befehl suspend
in den Hintergrund geschoben werden.
Konfiguration
Bei der Abmeldung wird ~/.bash_logout ausgeführt. Eine Subshell wird systemweit über /etc/bashrc und danach über ~/.bashrc konfiguriert. Im Verzeichnis /etc/skel existieren Vorlagen dieser Dateien, die neuen Benutzern ins Heimatverzeichnis kopiert werden.
Eingebaute Befehle
Die bash enthält zahlreiche, eingebaute Befehle und reservierte Wörter. Zu den eingebauten Befehlen zählen beispielsweise alias, cd, exit, help, kill, logout oder pwd und zu den reservierten Wörtern zählen die für die bash-Programmierung nötigen Schlüsselwörter wie case, for, function oder while.
Platzhalter
Als Platzhalter verwendet die bash den * für beliebig viele Zeichen und das ? für genau ein Zeichen. Mit [ und ] lassen sich auch Zeichenmengen und mit { und } sogenannte Klammererweiterungen angeben.
Ein- und Ausgabe, Umleitung
In der bash existieren drei sogenannte Standarddateien, die aber keine echten Dateien, sondern Dateideskriptoren sind, die von der bash wie Dateien behandelt werden. Es sind dies die Standardeingabe stdin, die Standardausgabe stdout und der Standardfehler stderr. Ein in der bash ausgeführtes Programm liest von der Standardeingabe, normalerweise ist das die Tastatur, und gibt das Ergebnis an die Standardausgabe weiter, normalerweise ist das der Bildschirm. Auch Fehlermeldungen werden via Standardfehler am Bildschirm ausgegeben. Im nachfolgenden Beispiel wird das Konzept der Standardeingabe und -ausgabe sichtbar: <syntaxhighlight lang="bash"> user$ echo "Dieser lan\ > ge Satz ers\ > treckt sich übe\ > r eine Zeile." Dieser lange Satz erstreckt sich über eine Zeile. </syntaxhighlight>
Diese drei Standarddateien können über ihren Kanal angesprochen werden, wobei 0 für die Standardeingabe, 1 für die Standardausgabe und 2 für den Standardfehler steht.
Die Standarddateien können auch umgeleitet werden, wofür die Zeichen >, < und | zur Verfügung stehen. Nachfolgend wird die Standardausgabe von ls *.txt in die Datei verzeichnis.info umgeleitet und danach von less als Standardeingabe eingelesen: <syntaxhighlight lang="bash"> user$ ls *.txt > verzeichnis.info user$ less < verzeichnis.info </syntaxhighlight>
Mit der Pipe lassen sich Ein- und Ausgaben auch direkt umleiten.
set-Optionen
Die bash verfügt über 27 Optionen, mit denen ein anderer Betriebsmodus eingestellt werden kann. Alle möglichen Einstellungen können mit <syntaxhighlight lang="bash"> user$ set -o </syntaxhighlight> aufgelistet werden, wobei mit der Option -o die Modi gelistet werden bzw. gesetzt werden und mit der Option +o die Option wieder aufgehoben wird. Das + ist dabei als durchgestrichenes - zu lesen. Gebräuchlich sind die Optionen noclobber, mit der der Ausgabeumleitung untersagt wird, vorhandene Dateien zu überschreiben, die Option noglob, bei der für Dateinamen keine Platzhalter wie * und ? möglich sind und die Option xtrace, bei der jedes Shell-Kommando vor der Ausführung nochmals ausgegeben wird, und zwar mit den intern vorgenommenen Erweiterungen, was bei der Fehlersuche nützlich sein kann.
Das Überschreiben der Ausgabeumleitung wird unterdrückt: <syntaxhighlight lang="bash"> user$ echo "hallo" > hallo.txt user$ echo "hallo" > hallo.txt user$ set -o noclobber user$ echo "hallo" > hallo.txt -su: hallo.txt: Kann existierende Datei nicht überschreiben. user$ set +o noclobber user$ echo "hallo" > hallo.txt </syntaxhighlight> Man kann Dateinamen mit Stern und Fragezeichen erzeugen. Vor der Abfrage mit ls *sh muss die Option wieder zurückgesetzt werden, denn sonst würde nach der Datei *sh gesucht werden. <syntaxhighlight lang="bash"> user$ set -o noglob user$ touch da*tei.sh user$ touch dat?ei.sh user$ set +o noglob user$ ls *sh da*tei.sh dat?ei.sh </syntaxhighlight> Die dritte Zeile zeigt die von der bash vorgenommenen Erweiterungen an: <syntaxhighlight lang="bash"> user$ set -o xtrace user$ ls *.txt + ls --color=auto hallo.txt test.txt text.txt hallo.txt test.txt text.txt </syntaxhighlight> Alle Optionen können auch mittels einer Kurzschreibweise gesetzt werden, beispielsweise ist set -C gleichbedeutend mit set -o noclobber.
Umgebungsvariablen
In der bash können Variablen auf mehrere Arten definiert werden. Grundsätzlich unterscheidet man zwischen „lokalen“ Variablen, die nur in der Shell gelten, in der sie definiert wurden, und „globalen“ Variablen, die auch in Sub-Prozessen zugewiesen sind. Lokale Variablen können erzeugt werden mit:
<syntaxhighlight lang="bash">
user$ var=var1
user$ var='var zwei'
user$ let var=var3
user$ declare var=var4
</syntaxhighlight>
und globale Variablen werden definiert mit:
<syntaxhighlight lang="bash">
user$ declare -x var=var5
user$ export var=var6
</syntaxhighlight>
Angesprochen werden die Variablen mit dem $-Zeichen:
<syntaxhighlight lang="bash">
user$ echo $var
</syntaxhighlight>
Statt „globale Variable“ ist allerdings im Unix-Umfeld der Ausdruck „Umgebungsvariable“ sehr viel geläufiger und passender, weil in manchen Programmiersprachen der Ausdruck „globale Variable“ eine andere Bedeutung als „Umgebungsvariable“ hat. Eine Wertzuweisung für eine „Umgebungsvariable“ wirkt nur auf „Unterprogramme“ (Kindprozesse), während manche Programmiersprachen es erlauben, Variablenwerte auch für „Oberprogramme“ zu setzen (etwa durch Voranstellen von \global
in TeX).
Eingebaute Umgebungsvariablen
Die bash verfügt über zahlreiche eingebaute Umgebungsvariablen, die auch häufig von anderen Kommandos ausgewertet werden. Bekannt sind die Variablen PATH für den Suchpfad, LANG für die Einstellung der Sprache oder PS1 für den Prompt.
Beispielsweise können die englischsprachigen Hilfeseiten vom ls mit dem nachfolgenden Befehl aufgerufen werden. Hier wird eine Sub-Shell erzeugt, darin die LANG-Umgebungsvariable überschrieben und anschließend der Befehl man ls ausgeführt. <syntaxhighlight lang="bash"> user$ LANG=en man ls </syntaxhighlight>
Programmierung
Bash-Programmierung unterscheidet sich in vielen Punkten von anderen Programmiersprachen. So wird beispielsweise bei der Verzweigung traditionell die Bedingung nicht von der Shell selbst ausgewertet, sondern an ein weiteres Programm übergeben:
<syntaxhighlight lang="bash"> if [ Bedingung ] ; then
# Falls Bedingung wahr ist, wird dies ausgeführt
else
# Falls Bedingung falsch ist, wird dies ausgeführt
fi </syntaxhighlight>
Die beiden eckigen Klammern sind keine Begrenzer, sondern ein Synonym für den integrierten (builtin) Shell-Befehl test
. Der Befehl test
prüft die Bedingung und liefert einen Rückgabewert 0 (wahr) oder 1 (falsch), der von der if
-Anweisung verarbeitet wird. Der oben angeführte Code ist also identisch mit der folgenden Schreibweise:
<syntaxhighlight lang="bash"> if test Bedingung ; then
# Falls Bedingung wahr ist, wird dies ausgeführt
else
# Falls Bedingung falsch ist, wird dies ausgeführt
fi </syntaxhighlight>
Heutzutage existiert jedoch auch ein eingebauter Ausdruck, der ohne externen Befehl auskommt, daher nicht mehr den Beschränkungen unterliegt, denen die Befehlsform unterlag, und so unter anderem auch keine Anführungszeichen um Variablen mehr benötigt:
<syntaxhighlight lang="bash"> if Bedingung ; then
# Falls Bedingung wahr ist, wird dies ausgeführt
else
# Falls Bedingung falsch ist, wird dies ausgeführt
fi </syntaxhighlight>
Hier kann die Bedingung nun z. B. auch Operatoren wie <
, >
(kleiner als und größer als), und =~
(Vergleich mit Regulärem Ausdruck) enthalten.
Diese Variante wird daher, wenn keine Kompatibilität zu älteren Versionen benötigt wird, generell empfohlen.
Jedoch kann auch weiterhin der Rückgabewert (0–127, wobei >0 = falsch) eines beliebigen Programmes verarbeitet werden. Nicht nur der des test
-Befehls. Als Beispiel wird hier der kill
-Befehl verwendet, um zu testen, ob ein Prozess mit einer bestimmten Nummer noch läuft bzw. in der Lage ist, Signale entgegenzunehmen:
<syntaxhighlight lang="bash">
if kill -0 1234 ; then
# Prozess 1234 läuft
else
# Prozess 1234 läuft nicht
fi </syntaxhighlight>
Sicherheit
Im September 2014 wurde eine gravierende Sicherheitslücke unter dem Namen Shellshock bekannt. Die seit langem bestehende Lücke ermöglicht, dass beim Start einer neuen Shell Schadcode, der per Umgebungsvariable eingefügt wurde, ungeprüft ausgeführt wird.<ref>ShellShock</ref><ref>ShellShock: Standard-Unix-Shell Bash erlaubt das Ausführen von Schadcode | heise online</ref> Die Lücke gilt seit Oktober 2014 als geschlossen.<ref name="lcamtuf-oct-1">Michał Zalewski: Bash bug: the other two RCEs, or how we chipped away at the original fix (CVE-2014-6277 and '78). In: lcamtuf blog. 1. Oktober 2014, abgerufen am 31. Oktober 2014 (english). </ref><ref name="redhat-1200223">Bash Code Injection Vulnerability via Specially Crafted Environment Variables (CVE-2014-6271, CVE-2014-7169). Red Hat, 2. Oktober 2014, abgerufen am 1. November 2014 (english). </ref>
Literatur
- Christian Meißner: Bash – Arbeiten und programmieren mit der Shell. Open Source Press, 2011, ISBN 978-3-941841-44-4.
- Karsten Günther: Bash - kurz & gut. 2008, ISBN 978-3-89721-533-7.
- Cameron Newham, Bill Rosenblatt: Learning the Bash Shell, 2nd Edition. O’Reilly & Associates, 1998, ISBN 1-56592-347-2.
- Jürgen Wolf, Stefan Kania: Shell-Programmierung. Das umfassende Handbuch. Galileo Computing, 4. Aufl. 2013, ISBN 978-3-8362-2310-2.
Weblinks
- Homepage
- Bash auf der GNU-Seite
- SelfLinux: Shellprogrammierung
- Advanced Bash-Scripting Guide ePub-Version (englisch)
Einzelnachweise
<references />