Die Bash Eingabeaufforderung anpassen
Anzeige zusätzlicher Informationen in der Eingabeaufforderung der Bash
Die Eingabeaufforderung der Bash ist nicht fest definiert sondern lässt sich vom Systemverwalter für alle Benutzer und vom einzelnen Benutzer für sich selbst anpassen. Dieser Artikel zeigt, wie man zusätzliche Informationen in die Eingabeaufforderung der Bash bringt.
Definition der Eingabeaufforderung
Inhalt und Aussehen der Eingabeaufforderung der Bash werden mittels der Umgebungsvariablen PS1
definiert. Wie die aktuelle Eingabeaufforderung definiert ist, erfährt man, wenn man den Inhalt der Variablen ausgibt:
uwe@Caboto:~$ echo $PS1
${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$
uwe@Caboto:~$
Was zunächst wie unverständlicher Programmcode aussieht, lässt sich relativ einfach aufschlüsseln:
${debian_chroot:+($debian_chroot)}
– Diese Sequenz sorgt für einen zusätzlichen Inhalt, falls die Shell sich gegenwärtig in einer chroot Umgebung befindet. Das ist normalerweise nicht der Fall und dann wird auch nichts ausgegeben.
\[\033[01;32m\]
– Mit \[…\]
wird generell eine Sequenz nicht-druckbarer Zeichen eingebettet, in diesem Fall \033[01;32m
, was eine Änderung der Farbe der nachfolgenden (wieder druckbaren) Zeichen zu grün ("light green") bewirkt. Diese sind
\u@\h
– \u
und \h
sind zwei von mehreren möglichen Makros, die in der Eingabeaufforderung verwendet werden können, \u
enthält den aktuellen Benutzernamen und \h
den aktuellen Rechnernamen. Hier wird noch ein @
Zeichen zwischen beide platziert.
Anschließend erfolgt mit \[\033[00m\]
eine Rücksetzung der zuvor geänderten Attribute, sodass der Text wieder normal in weiß erscheint, sodann ein Doppelpunkt :
und anschließend wieder mit \[\033[01;34m\]
eine Änderung der Farbe in blau ("light blue"), in welcher dann mit dem Makro \w
das gegenwärtige Arbeitsverzeichnis ausgegeben wird. Danach erfolgt mit \[\033[00m\]
wieder eine Rücksetzung der Attribute.
Zum Schluss wird mit dem Makro \$
tatsächlich nur ein $
Zeichen angezeigt, falls es sich beim aktuellen Benutzer nicht um den Systemverwalter root
handelt, wohingegen bei root
mit diesem Makro ein #
Zeichen angezeigt wird.
Ziel ist es nun, die EIngabeaufforderung so anzupassen, dass beim Wechsel in ein Verzeichnis, das der Versionsverwaltung mit Git unterliegt, der gegenwärtige Branch und das aktuelle Tag (sofern vorhanden) in der Eingabeaufforderung angezeigt werden.
Ein Git-Repository in der Bash anzeigen
Das Verzeichnis /home/uwe/ProjectDir/MyProject/
ist das Basisverzeichnis eines Projektes, das mit Git verwaltet wird. In der Bash könnte es ungefähr so aussehen:
Mit dem Befehl git branch
oder git rev-parse -abbrev-ref HEAD
kann man herausfinden, auf welchem Branch in einem Git-Repository man sich befindet:
$ git rev-parse --abrev-ref HEAD
master
$
Befindet man sich nicht in einem Verzeichnis eines Git-Repositories, erfolgt eine Fehlermeldung:
$ git rev-parse --abrev-ref HEAD
fatal: Kein Git-Repository (oder irgendeines der Elternverzeichnisse): .git
$
Um herauszufinden, ob man es ein Tag gibt, kann man den Befehl git describe
verwenden. Dieser gibt die gleiche Fehlermeldung wie oben aus, wenn man sich nicht in einem Git-Repository befindet und eine andere, wenn es im Repository kein Tag gibt:
$ git describe
fatal: Keine Namen gefunden, kann nichts beschreiben.
$
Wenn es ein Tag gibt, wird dieses angezeigt:
$ git describe
v3.2.12
$
Um diese Informationen mit Hilfe eines einzigen Befehls verfügbar zu machen, müssen wir zunächst eine Bash-Funktion definieren, die genau diese Inhalte ausgibt.
Eine Funktion current_git_branch
definieren
Der geeignete Ort für Funktionsdefinitionen ist die benutzerspezifische Konfigurationsdatei der Bash, .bashrc
, die beim Starten einer Bash aufgerufen und ausgeführt wird. Sie ist grundsätzlich im Stammverzeichnis des Benutzers vorhanden und enthält bereits einige Einstellungen.
Eine weitere, bessere Möglichkeit wäre es, Funktionsdefinitionen in einer zusätzlichen Datei, zum Beispiel .bash_functions
unterzubringen und diese Datei dann in der .bashrc
einzubinden. Das Einbinden der .bash_functions
sollte wie folgt aussehen und relativ am Anfang der .bashrc
erfolgen, da man ja möglicherweise noch an späterer Stelle innerhalb der .bashrc
auf die definierten Funktionen zugreifen will:
if [ -f ~/.bash_functions ]; then
. ~/.bash_functions
fi
Das bedeutet: Wenn es die Datei .bash_functions
im Stammverzeichnis des Benutzers (~
) gibt, wird sie eingebunden ("sourced") und die darin enthaltenen Funktionsdefinitionen ausgeführt, ansonsten passiert gar nichts.
Die Definition der Funktion current_git_branch
– die auch völlig anders heißen kann – sieht wie folgt aus:
function current_git_branch {
local version=$(git describe 2>/dev/null);
local branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null);
if [[ -n $branch ]];then
echo " [$branch/$version]";
fi
}
Die Ausgabe des Befehls git describe
wird mittels $(…)
erfasst und in der (nur in dieser Funktion gültigen) Variablen version
gespeichert. Wichtig ist , dass mit 2>/dev/null
eventuelle Fehlerausgaben ins Nichts geschickt werden, sodass bei der späteren Ausgabe der Variablen im Fehlerfall nichts ausgegeben wird.
In gleicher Weise wird die Ausgabe von git rev-parse -abbrev-ref HEAD
in der Variablen branch
gespeichert.
Sollte danach die Variable branch
nicht leer sein, wird der Inhalt von branch
und version
mit /
getrennt in eckigen Klammern und mit einem Leerzeichen davor ausgegeben.
Mit einer neuen Bash oder mittels "sourcen" der .bashrc
(oder der .bash_functions
) lässt sich die Funktion testen. Einfach den Befehl current_git_branch
ausführen. Wenn das gegenwärtige Verzeichnis nicht unter Versionskontrolle steht, wird nichts erscheinen, anderfalls müsste z.B. [master/]
oder [master/1.2.3]
ausgegeben werden, je nachdem in welchem Branch man sich gerade befindet und ob es ein Tag gibt.
Die Funktion der Eingabeaufforderung hinzufügen
Die Ausgabe des Befehls current_git_branch
wird nun mittels $(current_git_branch)
der Eingabeaufforderung an einer geeigneten Stelle hinzugefügt, am besten nach dem gegenwärtigen Verzeichnis und vor dem $
Zeichen. Dazu muss die Definition der Variablen PS1
in der .bashrc
geändert werden:
Die Definition von PS1
endet üblicherweise wie oben beschrieben:
PS1='...\w\[\033[00m\]\$ '
Das wird geändert zu:
PS1='...\w$(current_git_branch)\[\033[00m\]\$ '
Sobald man eine neue Bash gestartet oder die .bashrc
erneut eingebunden hat ist die neue Eingabeaufforderung wirksam:
Weiterführende Literatur
Bash Prompt HOWTO: Chapter 6. ANSI Escape Sequences: Colours and Cursor Movement