[[Vorlage(Getestet, general)]] {{{#!vorlage Wissen [:Editor: Einen Editor öffnen] [:Terminal: Ein Terminal öffnen] }}} [[Inhaltsverzeichnis(3)]] [[Bild(Wiki/Icons/terminal.png, 48, align=left)]] Die [wikipedia:Bourne-again_shell:Bash] ist so etwas wie die Standard-Shell [2] unter Linux. Dabei steht Bash für '''B'''ourne '''a'''gain '''Sh'''ell. Erweiterte Einstellungsmöglichkeiten werden im Artikel [:Bash/bashrc:] erklärt. = Grundlagen = Eine grundlegende Übersicht findet man im Artikel [:Shell:]. Im weiteren werden einige Funktionen beschrieben, die Bash-spezifisch sind, sich aber durchaus auch in anderen Shell-Umgebungen wiederfinden können. Die Bash hat ihr eigenes Hilfesystem, welches jeden ihrer Befehle erklärt. Dieses beschreibt der Artikel [:Bash/Hilfe:]. == History == In der Bash ist es möglich, die zuletzt eingegebenen Befehle mit den Pfeiltasten ([[Vorlage(Tasten, hoch)]]/[[Vorlage(Tasten, runter)]]) durchzublättern oder zu durchsuchen. Dies vereinfacht die Bedienung in der Praxis enorm. Als Standardwert werden die letzten 500 Befehle gespeichert. Einstellen lässt sich dieser Wert mit einem Editor [1] in der Datei '''~/.bashrc'''. Mit dem Eintrag `HISTSIZE=2000` wird die History z.B. auf 2000 Befehle erweitert. === Durchsuchen === Die Befehlsliste lässt sich mit der Tastenkombination [[Vorlage(Tasten, Strg+r)]] durchsuchen. Durch Eingabe von {{{#!vorlage Befehl history }}} lässt sich auch eine Liste der eingegebenen Befehle ausgeben, die man mit Hilfe von [:grep:] filtern kann: {{{#!vorlage Befehl history | grep -E webserver }}} gibt zum Beispiel alle Befehle an, die die Zeichenfolge "webserver" enthalten haben. Indem man einer Zeichenfolge ein Ausrufezeichen voranstellt, sucht die Bash in der History nach dem letzten Eintrag, der mit den selben Zeichen beginnt und führt diesen Befehl aus. === Gezieltes Blättern aktivieren === (ab 23.04 nicht mehr nötig, funktioniert dort schon ohne diesen Eingriff)\\ Um die History der Bash gezielt zu durchblättern, lohnt es sich, folgende Zeilen in der Datei '''/etc/inputrc''' zu entkommentieren [1]: {{{ # "\e[5~": history-search-backward # "\e[6~": history-search-forward }}} Möchte man diese Funktion nur für einen bestimmten User aktivieren und nicht systemweit, so kopiert man die Datei '''/etc/inputrc''' nach '''/home/$USER/.inputrc''', und nimmt die Änderung dort vor. Durch Drücken der Tasten [[Vorlage(Tasten, "Bild auf")]] und [[Vorlage(Tasten, "Bild ab")]] kann man die History der Bash anschließend nach Einträgen durchsuchen, welche mit den Worten beginnen, die ''vor der aktuellen Cursorposition'' stehen. Beispiel: {{{#!vorlage Befehl sudo vi⌷ /etc # ⌷ = Cursor }}} Drückt man jetzt [[Vorlage(Tasten, "Bild auf")]] oder [[Vorlage(Tasten, "Bild ab")]], wird die History nach Einträgen durchblättert, welche mit '''''sudo vi''''' beginnen. {{{#!vorlage Hinweis Wird die '''/home/$USER/.inputrc''' verwendet, muss darin in der ersten Zeile {{{ $include /etc/inputrc \}}} stehen, damit die Einstellungen darin ebenfalls beachtet werden. }}} [[Anker(history_blacklist)]] === Bestimmte Befehle ausschließen === Will man nur bestimmte Befehle nicht in der History speichern, so kann man mit der Variablen `HISTIGNORE` eine schwarze Liste erstellen. Hierzu trägt man beispielsweise {{{HISTIGNORE="truecrypt -P*:sudo*" }}} in die Datei '''~/.bashrc''' ein [1]. Dadurch werden alle Befehle, die mit `truecrypt -P` oder mit `sudo` beginnen, von der History ausgeschlossen. === Zeitstempel hinzufügen === Möchte man den Zeitpunkt der Eingabe von Befehlen in der History speichern, so kann dies mit der Variablen `HISTTIMEFORMAT` erfolgen. Hierzu trägt man {{{HISTTIMEFORMAT="%F %T " }}} in die Datei '''~/.bashrc''' ein [1]. Allerdings sollte beachtet werden, dass Zeitstempel nicht rückwirkend gesetzt werden können, wodurch diese bei bereits in der Historie befindlichen Einträgen nicht zutreffend sind. Beispielausgabe: {{{ 400 2013-01-10 08:00:01 ls 401 2013-01-10 08:00:17 top 402 2013-01-10 08:01:04 ps aux }}} === Am häufigsten verwendete Befehle === Wer interessehalber ein Liste der am häufigsten verwendeten Befehle benötigt, benutzt den folgenden Befehl: {{{#!vorlage Befehl history | awk '{CMD[$2]++;count++;}END { for (a in CMD)print CMD[a] " " CMD[a]/count*100 "% " a;}' | grep -v "./" | column -c3 -s " " -t | sort -nr | nl | head -n10 }}} === Löschen === Mit dem Befehl {{{#!vorlage Befehl history -c }}} löscht man die komplette History der aktiven Shell. Möchte man dazu noch die History vorheriger Sitzungen aus der Datei '''~/.bash_history''' löschen, kann man diese Datei mit den Befehlen {{{#!vorlage Befehl history -c history -w }}} mit der leeren History der aktiven Shell überschreiben. Einzelne Zeilen lassen sich löschen mit {{{#!vorlage Befehl history -d NNN }}} `NNN` repräsentiert hierbei einen dreistelligen Zahlenwert der entsprechenden Zeile. === Deaktivierung === Es kann unter bestimmten Umständen sinnvoll sein, die History der Bash zumindest für `root` zu deaktivieren. Dazu muss man in der Datei '''~/.bashrc''' folgende Zeile eintragen: {{{ unset HISTFILE }}} und die Datei '''~/.bash_history''' löschen. === Sofort speichern === Man kann die History auch sofort nach der Ausführung jeden Befehls speichern lassen. Das hilft beispielsweise zum einen bei dem Problem unter einigen Versionen wie Ubuntu 14.04 und anderen Varianten, dass die History nicht gespeichert wird, außer wenn man `exit` eingibt. Zum anderen kann man dadurch die komplette History direkt in neu geöffnete Terminal-Tabs übernehmen lassen, obwohl die anderen Tabs noch nicht geschlossen sind. Dazu muss man in der Datei '''~/.bashrc''' folgende Zeile eintragen: {{{ PROMPT_COMMAND="history -a" }}} Möchte man erreichen, dass sogar bei parallel geöffneten Tabs bzw. Fenstern die History aus allen Tabs nach jedem Befehl gespeichert und dadurch jedem bereits geöffneten anderen Tab sofort zur Verfügung gestellt wird, ohne dafür einen neuen Tab öffnen zu müssen, trägt man stattdessen folgende Zeile ein: {{{ PROMPT_COMMAND="history -a; history -c; history -r" }}} {{{#!vorlage Hinweis Dabei wird die temporäre History-Liste erst in die History-Datei angehangen und gespeichert, anschließend die History-Liste gelöscht und anschließend die dann komplette History aus der History-Datei neu in die History-Liste eingelesen, um sofort die vollständige History aus der Datei in der durchscrollbaren Liste zur Verfügung zu haben. }}} Diese Lösung klingt zwar zunächst am vorteilhaftesten für viele Zwecke, jedoch ist so die Wiederholung des letzten Befehls aus dem selben Tab durch die Pfeiltasten dann nicht mehr direkt möglich, da sich dann Befehle aus den anderen Tabs vordrängeln können, so dass man die Pfeiltaste nach oben dann ggf. mehrfach betätigen muss. {{{#!vorlage Warnung Wenn dies beispielsweise ein Löschbefehl für das aktuelle Verzeichnis war, kann sich dies bei unbedachtem Bestätigen des falschen Befehls sehr ungünstig auswirken. }}} Dadurch hat man allerdings sofort alle Befehle, Optionen und Parameter in allen Tabs zur Verfügung, ohne sie in neue Tabs kopieren zu müssen, wenn man sie dort für weitere Vorgänge braucht. Dazu reicht es aus, in dem Tab, wo man die komplette History aller Tabs sofort benötigt, einmal kurz [[Vorlage(Tasten, Enter)]] zu betätigen, damit die History von allen Tabs dort neu eingelesen wird. === Historie für alle Instanzen der Bash zusammenfassen === Arbeitet man mit mehreren Terminals gleichzeitig, so wird für jedes Terminal separat eine History geführt. Man kann jedoch alle Befehle in einer einzigen History zusammenführen. Dazu ergänzt man am Ende von `~/.bashrc` folgende Textzeile: {{{#!vorlage Befehl PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND" }}} Mit `history -a` wird der momentane Verlauf der Bash an eine gemeinsame History-Datei gehängt. Anschließend wird mit `history -c` der Verlauf des Terminalfensters entfernt und mit `history -r` wird die ganze, vollständige History wieder eingelesen. == Autovervollständigung == Die Bash bietet die Möglichkeit, Befehle und Dateinamen nach dem Eingeben der ersten Zeichen automatisch zu vervollständigen. Dies erreicht man durch drücken der Tabulatortaste [[Vorlage(Tasten, tab)]]. Beispiel: {{{#!vorlage Befehl cd /home/bla }}} ergibt durch das Drücken von [[Vorlage(Tasten, tab)]]: {{{#!vorlage Befehl cd /home/blackbird }}} Allerdings nur, wenn der Ordner '''/home/blackbird''' existiert. Sollte es die Ordner blackbird_1 und blackbird_2 geben, macht er das: {{{#!vorlage Befehl cd /home/bla }}} ergibt das Drücken von [[Vorlage(Tasten, tab)]]: {{{#!vorlage Befehl cd /home/blackbird_ }}} und wartet, bis ein zusätzlicher Buchstabe eingegeben wird. Man kann sich mittels "Doppeltab", also das erneute Drücken von Tab dann auch die zur Verfügung stehenden Möglichkeiten zur Vervollständigung ausgeben lassen. Das Geräusch (Piepen), das ertönt, wenn die Autovervollständigung aufgrund von Mehrdeutigkeiten fehlschlägt, lässt sich durch folgenden Eintrag z.B. in der '''~/.bashrc''' (systemweit: '''/etc/bash.bashrc''') ausschalten: {{{set 'bind bell-style none' }}} In '''/etc/inputrc''' lassen sich ebenfalls einige (systemweite) Änderungen vornehmen: {{{set bell-style none --> Ruhe set bell-style visible --> Window flasht }}} Möchte man diese Funktion nur für einen bestimmten User aktivieren (und nicht systemweit), so kopiert man die Datei '''/etc/inputrc''' nach '''/home/$USER/.inputrc''' und nimmt die Änderung dort vor. Die Bash lässt sich durch den folgenden Eintrag dazu bewegen, die existierenden Möglichkeiten gleich anzuzeigen (ohne den Doppeltab): {{{set show-all-if-ambiguous on }}} Groß/Kleinschreibung ignorieren: {{{set completion-ignore-case on }}} Normalerweise komplettiert die Bash soweit, wie eindeutige Möglichkeiten vorhanden sind und wartet dann auf eine Eingabe durch den Benutzer. Man kann aber auch durch die vorhandenen Möglichkeiten einfach 'durchtabben', indem man in '''/etc/inputrc''' folgendes (nach der if mode=emacs Zeile) einträgt: {{{Control-i: menu-complete }}} Um doch noch die Variante mit Anzeige der Möglichkeiten zu Verfügung zu haben, muss diese Zeile eingefügt werden: {{{"\C- ": complete }}} Jetzt kann man mit Tab durch die Möglichkeiten wechseln, und mit Strg-Leertaste die Möglichkeiten anzeigen lassen. === Programmierbare Vervollständigung der Bash aktivieren === Mit dieser Funktion lässt sich die Autovervollständigung nicht nur für Befehle und Dateinamen, sondern auch zum Beispiel für Optionen verwenden. Die programmierbare Vervollständigung der Bash lässt sich aktivieren, in dem man in '''/etc/bash.bashrc''' oder '''~/.bashrc''' den folgenden Block wie in diesem Beispiel {{{# aktiviert Bashvervollständigung in interaktiven Shells if [ -f /etc/bash_completion ]; then . /etc/bash_completion fi }}} durch Entfernen der '''#'''-Zeichen am Zeilenanfang einkommentiert. Ausprobieren lässt es sich zum Beispiel mal mit {{{#!vorlage Befehl apt-get install }}} und dem Drücken der [[Vorlage(Tasten, Tab)]]-Taste. Sollte die programmierbare Vervollständigung selbst nach erneutem Einloggen nicht funktionieren, muss unter Umständen das Paket '''bash-completion''' installiert werden. == Wildcards == Joker oder Wildcards können für beliebige Zeichen stehen. Zum Beispiel kann man mit {{{#!vorlage Befehl ls *.png }}} alle Dateien mit der Endung ''.png'' anzeigen. || `*` || ersetzt beliebig viele Zeichen || || `?` || ersetzt genau ein Zeichen || Es ist auch möglich, Textteile aus Wortgruppen auszuwählen: || `{WORT1,WORT2,WORT3}` || Wenn eines der genannten Wörter vorkommt || An der Stelle, wo diese Ersetzung auftritt, muss eines der aufgeführten Wörter vorkommen. Zum Beispiel können wir auf diese Weise alle .png Dateien anzeigen: {{{#!vorlage Befehl ls *.{png,PNG,Png,pNg,pnG,PNg,pNG} }}} Es gibt auch die Möglichkeit, ein einzelnes Zeichen aus einer Liste an einer Stelle zu erwarten: || ` [abcd] ` || wenn einer der Buchstaben vorkommt || Obiges Beispiel lässt sich also auch so erreichen: {{{#!vorlage Befehl ls *.[jJpP][pPnN][gG] }}} findet .jpg und .png Dateien (würde jedoch auch *.ppg- oder *.jng-Dateien finden, wenn es sie gäbe). Wobei man mit || ` [j-p] ` || auch alle Buchstaben von j bis p auswählen kann || {{{#!vorlage Befehl ls *.[k-p][m-r]g }}} findet nun zum Beispiel auch eine *.log-Datei. || ` *(MUSTERLISTE)` || findet keins oder mehrere aus der Musterliste || || ` +(MUSTERLISTE) ` || findet mindestens eins aus der Musterliste || || ` !(MUSTERLISTE)` || schließt Muster aus der Liste aus || {{{#!vorlage Befehl ls !(*.jpg|*.JPG) ## oder *.!(jpg|JPG) }}} findet alles außer *.jpg- und *.JPG-Dateien. == Spezielle Aktionen, wenn ein Befehl nicht gefunden wird == Sollte ein eingegebener Befehl nicht gefunden werden, so wird standardmäßig [:command-not-found:] aufgerufen. Das passiert über die Funktion `command_not_found_handle`. Diese kann auch umdefiniert werden. Ein Beispiel dafür ist das Abfangen eines Tipp-/Eingabefehlers beim Benutzen der Vervollständigung: Man tippt manchmal zwei Buchstaben, dann [[Vorlage(Tasten, Tab)]] und erwischt dann beim Drücken von [[Vorlage(Tasten, Enter)]] auch die [[Vorlage(Tasten, #)]]-Taste. Abfangen kann man das mit folgender Funktion: {{{#!code bash command_not_found_handle() { cmd_ohne_hash="${1/\#}" if [ "$1" != "$cmd_ohne_hash" ] then shift echo "$cmd_ohne_hash $@" $cmd_ohne_hash $@ return $? fi } }}} Dieser Funktion fehlt aber dann die Fähigkeit, [:command-not-found:] aufzurufen. Günstiger ist es also die bestehende Funktion zu erweitern. = Hintergrundprozesse = == Prozess direkt im Hintergrund starten == Um einen Prozess im Hintergrund zu starten, hängt man einfach ein `&` an den Befehl an: {{{#!vorlage Befehl /usr/bin/xeyes & }}} Möchte man den Prozess jedoch zusätzlich von der Benutzer-Sitzung lösen (damit diese geschlossen werden kann, während der Prozess weiterläuft) ist die Verwendung von `disown` notwendig: {{{#!vorlage Befehl /usr/bin/xeyes & disown }}} Es empfiehlt sich aber, die vom Prozess erzeugte Ausgabe auf `stdout` bzw. `stderr` entweder in eine Logdatei umzuleiten. Dazu verwendet man bspw. `nohup` (wird wie `sudo` VOR dem eigentlichen Befehl notiert): {{{#!vorlage Befehl nohup /usr/bin/xeyes > xeyes.log 2>&1 & }}} == Prozess unterbrechen und/oder in den Hintergrund schicken == Wenn man ein Programm oder einen Prozess in der Shell gestartet hat, kann man ihn mit der Tastenkombination [[Vorlage(Tasten, Strg+Z)]] einfrieren. Nun ist die Shell wieder freigegeben und man kann zum Beispiel Daten, die vom Prozess verwendet werden, bearbeiten oder sichern. Mit dem Befehl {{{#!vorlage Befehl fg }}} läuft der Prozess anschließend wieder (auf der Shell) weiter. Möchte man die Shell dauerhaft freigeben (also während der Prozess weiterläuft), gibt man statt `fg` {{{#!vorlage Befehl bg }}} ein, um den Prozess in den Hintergrund zu schicken. Nun kann man die Shell weiter benutzen oder auch schließen, während der Prozess im Hintergrund läuft. = Skripte = Viele Aufgaben lassen sich mit Hilfe von Bash-Skripten automatisieren. Unter [:Skripte:] wird eine Beispielsammlung mit Skripten zusammengetragen. Wer selbst in das Thema einsteigen möchte, sollte sich den Artikel [:Shell/Bash-Skripting-Guide_für_Anfänger:] anschauen. = Links = == intern == * [:Shell:] - Generelle Einführung in die Shell und in das Scripting * [:Bash/Prompt:Bash-Prompt] - Artikel zur persönlichen Anpassung des Prompts * [:Bash/Hilfe:] - Hilfe zu Befehlen und Kommandos der Bash aufrufen * [:Crudini:] - Ini-Dateien in Shellskripten auslesen und modifizieren == extern == * [http://www.gnu.org/savannah-checkouts/gnu/bash/manual/ GNU Bash manual] {en} – Das definitive Referenz-Handbuch bei GNU.org in verschiedenen Formaten (HTML, PDF, …) * [http://bin-bash.de/ bin-bash.de] {de} bietet eine gute Einführung in die Bash * [https://tuxhausen.files.wordpress.com/2008/09/tuxhausen_linux-kurs.pdf Tuxhausen Linux-Kurs (PDF)] {de} - speziell zur Shell * [http://www-user.tu-chemnitz.de/~hot/unix_linux_werkzeugkasten/bash.html Die GNU-Shell Bash (Bourne Again SHell)] {de} - Alles Relevante zur Bash * [http://de.wikibooks.org/wiki/Linux-Praxisbuch:_Shellprogrammierung Linux-Praxisbuch: Shellprogrammierung] {de} * [http://mywiki.wooledge.org/BashGuide BashGuide] {en} - sehr gutes Handbuch mit viel Hintergrundinformation * [http://mywiki.wooledge.org/BashGuide/Practices Practices] {en} - praktische Beispiele * [http://mywiki.wooledge.org/BashPitfalls Bash-Pitfalls] {en} - beliebte Benutzerfehler und andere Fallgruben * [http://www.tldp.org/guides.html#bbg Bash Guide for Beginners] {en} von Machtelt Garrels * [http://www.tldp.org/guides.html#abs Advanced Bash-Scripting Guide] {en} von Mendel Cooper * [http://bash.cyberciti.biz/guide/Main_Page Linux Shell Scripting Tutorial (LSST) v2.0] {en} * [http://ibiblio.org/pub/Linux/docs/HOWTO/Bash-Prog-Intro-HOWTO BASH Programming - Introduction HOW-TO] {en} * [http://www.ibm.com/developerworks/library/l-bash.html IBM] {en} - Bash by example, Part 1 # tag: Shell