ubuntuusers.de

Bash

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:

Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.

Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:

Wiki/Icons/terminal.png Die Bash ist so etwas wie die Standard-Shell [2] unter Linux. Dabei steht Bash für Bourne again Shell. 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 ( / ) 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 Strg + R durchsuchen. Durch Eingabe von

history 

lässt sich auch eine Liste der eingegebenen Befehle ausgeben, die man mit Hilfe von grep filtern kann:

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 Bild ↑ und Bild ↓ kann man die History der Bash anschließend nach Einträgen durchsuchen, welche mit den Worten beginnen, die vor der aktuellen Cursorposition stehen. Beispiel:

sudo vi⌷ /etc     # ⌷ = Cursor 

Drückt man jetzt Bild ↑ oder Bild ↓ , wird die History nach Einträgen durchblättert, welche mit sudo vi beginnen.

Hinweis:

Wird die /home/$USER/.inputrc verwendet, muss darin in der ersten Zeile

$include /etc/inputrc

stehen, damit die Einstellungen darin ebenfalls beachtet werden.

⚓︎

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:

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

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

history -c
history -w 

mit der leeren History der aktiven Shell überschreiben.

Einzelne Zeilen lassen sich löschen mit

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"

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.

Achtung!

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

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 Tab ⇆ . Beispiel:

cd /home/bla 

ergibt durch das Drücken von Tab ⇆ :

cd /home/blackbird 

Allerdings nur, wenn der Ordner /home/blackbird existiert. Sollte es die Ordner blackbird_1 und blackbird_2 geben, macht er das:

cd /home/bla 

ergibt das Drücken von Tab ⇆ :

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

apt-get install 

und dem Drücken der 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

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:

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:

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

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

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 Tab ⇆ und erwischt dann beim Drücken von auch die # -Taste. Abfangen kann man das mit folgender Funktion:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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:

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

/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):

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

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

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.

intern

  • Shell - Generelle Einführung in die Shell und in das Scripting

  • 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

Diese Revision wurde am 11. November 2023 16:36 von tomtomtom erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Shell