Pimp your (Bash) Prompt
Du bist gelangweilt von dem hans@wurst:~$ – Prompt deiner Bash? Möchtest gerne mehr Informationen gezeigt bekommen? Du hättest gerne Augenschmerzen vor lauter Farben?
In folgendem Artikel werde ich erklären, wie du
- Deinen Prompt personalisieren,
- einfärben,
- und visuell vollkommen verunstalten kannst.
(Kleiner Hinweis vorweg: Der eine oder andere mag es bereits bemerkt haben, ich beziehe mich im ganzen Artikel ausschliesslich auf die Bash. Selbstverständlich lassen sich die meisten anderen Shells ebenfalls über ihre Variablen individualisieren. Das soll keinerlei Wertung sein, ich habe einfach keine Zeit, mich mit anderen Shells wie der zsh zu beschäftigen. Sollte also jemand von euch Zeit und Lust haben einen Artikel dazu loszuwerden, lade ich ihn hiermit herzlich ein. :) )
Grundlagen
In der Bash wird der primäre Prompt über die Variable PS1 gesteuert. Neben PS1 existieren noch PS2, PS3 und PS4, wobei für uns nur die ersten Beiden interessant sind.
- PS1 – In dieser Variable wird der primäre Prompt der Bash gespeichert. Der Standardwert ist in dem meisten Linuxdistributionen \u@\h:\w\$.
- PS2 – Der sekundäre Prompt. Dieser Prompt wird ausgegeben, wenn auf eine Eingabe des Users gewartet wird. Der Standardwert ist >. Der sekundäre Prompt lässt sich beispielsweise mit einem unvollendeten Befehl wie “ls |” ausgeben.
- PS3 – wird vom internen select Befehl verwendet.
- PS4 – Die Variable “PS4″ wird vor den Debug-Meldungen ausgegeben, die durch die Shell-Option “-x” [execute trace] ausgegeben werden. Der Standardwert ist hier meist +.
Die Veränderungen treten sofort ein, bleiben jedoch erst dann erhalten, wenn der “export”-Befehl in die Datei ~/.bashrc eingetragen wird.
Zunächst löschen wir einfach mal den Inhalt von PS1:
unset $PS1
Nun fehlt jegliche Eingabeaufforderung. Das bedeutet natürlich nicht, dass keine Befehle mehr eingegeben werden können. Es gibt einfach keinen Prompt mehr, der ausgegeben werden könnte.
Mit export können Umgebungsvariablen gesetzt werden. Ein schnelles:
export $PS1="pimp my shell >"
zum Beispiel erzeugt folgenden sinnlosen aber witzigen Prompt:
pimp my shell >
Aber wie lasse ich mir Informationen statt nur einfachen Text prompten ausgeben? Über so genannte Escape-Sequenzen. Nun wird es interessant. Es gibt einen ganzen Haufen Escape-Sequenzen, welche etwa Arbeitsverzeichnis, Benutzername oder Uhrzeit ausgeben:
| \a | Das ASCII-Zeichen für eine Glocke (“\007″ sollte auch funktionieren). Dies erzeugt einen Ton, welcher (falls vorhanden) aus dem PC-Speaker tönt. Das ist aber nicht zu empfehlen, da dieser dann bei jedem ausgegebenen Prompt mit dieser Escape-Sequenz der Speaker einen nervigen Ton von sich gibt. |
| \d | Zeigt das Datum im “Wochentag Monat Datum”-Format (Bspw. “Tue May 26″) |
| \D{format} | Der Inhalt der beiden geschweiften Klammern wird an strftime gesendet und das Ergebnis zurück in den Prompt-String. Leer gelassen erzeugt das meist ein locale-Spezifisches Datum. Die geschweiften Klammern sind pflicht. |
| \e | Ein ASCII Escape-Zeichen (“\033″ sollte auch funktionieren.) |
| \h | Der Hostname bis zum ersten “.” |
| \H | Der komplette Hostname |
| \j | Gibt die Anzahl der Hintergrundprozesse aus. |
| \l | Name der Shell |
| \n | Erzeugt eine neue Zeile (Ja, Prompts können mehrzeilig sein). |
| \r | Carriage-Return |
| \s | Der Name der Shell. Logischerweise Bash |
| \t | Die Zeit im 24-Stunden HH:MM:SS Format |
| \T | Die Zeit im 12-Stunden HH:MM:SS Format |
| \@ | Die Zeit im 12-Stunden AM/PM Format |
| \A | Die Zeit im 24-Stunden HH:MM Format |
| \u | Name des Benutzers |
| \v | Versionsnummer der Bash (Bspw. 3.2) |
| \V | Wie /v, jedoch mit Patch-Level (Bspw. 3.2.25) |
| \w | Das aktuelle Arbeitsverzeichnis, wobei $HOME mit einer Tilde (~) abgekürzt wird. |
| \W | Das aktuelle Arbeitsverzeichnis (, jedoch ohne höhere Ebenen), wobei $HOME mit einer Tilde (~) abgekürzt wird. |
| \! | Die History-Nummer des Befehls. Dies kann natürlich je nach .bash_history variieren. |
| \# | Anzahl der bereits aufgerufenen Kommandos während der Shell-Session |
| \$ | Wenn UID = 0, ein #, andernfalls ein $. Zu deutsch: Normale User sehen ein “$”, Root ein “#”. |
| \nnn | Zeichen entsprechend der oktalen Zahl nnn |
| \\ | Ein Backslash |
| \[ | Beginn einer Sequenz von nicht-darstellbaren Zeichen. |
| \] | Ende einer Sequenz von nicht-darstellbaren Zeichen |
Damit lässt sich schon viel anstellen. Sinnvoll sind und bleiben natürlich Benutzername, Verzeichnis und Hostname. Nach ein wenig herumspielen könnte der Inhalt von PS1 zum Beispiel so aussehen:
[\d \A, Bash Version \V, \# Commands, \j Jobs, tty #\l]\n[\u@\H:\w] \$
, was bei mir in etwa folgenden Prompt erzeugt:
[Mo Dez 10 23:05, Bash Version 3.2.25, 116 Commands, 0 Jobs, tty #2]
[jxn@david:~] $
Die eckigen Klammern sind übrigens reine Kosmetik ;)
Farben
| Farbe | VG / HG |
| Schwarz | 30 / 40 |
| Rot | 31 / 41 |
| Grün | 32 / 42 |
| Braun | 33 / 43 |
| Blau | 34 / 44 |
| Violett | 35 / 45 |
| Cyan | 36 / 46 |
| Weiss | 37 / 47 |
Zufrieden mit der Ausgabe? Weiter gehts mit optischer hervorhebung durch Farben.
Farbangaben müssen über die Escape-Sequenz \e (/033 sollte auch funktionieren) eingeleitet werden. Diese Escape-Sequenz wird jedoch vom genutzten Terminal verarbeitet, nicht von der Bash. Deswegen funktioniert die Einfärbung von Prompts auch nicht überall, selbst wenn die Bash genutzt wird.
Eine Farbangabe besteht aus dem Escape-Zeichen “\e”, den Farbcodes “x;yy;zz” (Eigenschaft;Vordergrund;Hintergrund) und einem abschliessendem “m”. Beispiele für Farbcodes können der nebenstehenden Tabelle entnommen werden, wobei die 30er für die Vordergrund- und die 40er für die Hintergrundfarben stehen. Sinnvolle Werte für die Schrifteigenschaft (x) sind: 0 (Standard), 1 (heller), 22 (nicht heller), 4 (unterstrichen), 24 (nicht unterstrichen), 5 (blinkend), 25 (nicht blinkend), 7 (invers), 27 (nicht invers).
Die Codes in der Farbangabe können übrigens in beliebiger Reihenfolge gesetzt werden. Ein “5;41;32″ ergibt Bspw. das Gleiche wie ein “41;5;32″, das Entscheidende ist der Code, nicht die Reihenfolge.
Färben wir einfach mal den oben erwähnten Standardprompt “\u@\h:\w\$” hellgrün mit einem rotem Hintergrund:
export PS1="\e[1;32;41m\u@\h:\w\$ "
Das Problem: Nun ist nicht nur der Prompt hellgrün, sondern der gesamte Text in unserer Shell. Das lässt sich mit einem schliessenden "\e[0m" verhindern. Auf diese Weise wird die Farbangabe auf Null zürückgesetzt. Ein
export PS1="\e[1;32;41m\u@\h:\w\$\e[0m "
sieht schon gleich viel besser aus. Aber das reicht leider immer noch nicht. Die sowieso nicht darstellbaren Zeichen unserer Farbangaben müssen mit den Sequenzen "\[" und "\]" auch als solche gekennzeichnet werden. Sonst gibt es hässliche Darstellungsfehler, sollte ein Kommando einmal das rechte Ende des sichtbaren Bereichs erreichen. Das Ergebnis sollte also wie folgt aussehen:
export PS1="\[\e[1;32;41m\u@\h:\w\$\e[0m\] "
Natürlich können in einem Prompt auch mehrere Farbangaben verwendet werden. Aber jeder sollte für sich entscheiden, wieviel Bunt seine Augen ertragen können. ;)
Noch nicht genug? Bashish rocks your socks!
Bashish ist eine Theme-Engine für allerlei Terminals und Shells. Mit Bashish lassen sich Farbe, Schriftart, Transparenz und Hintergrundbild für einzelne Programme unabhängig voneinander personalisieren. Ausserdem kann man mit Bashish die Prompts verbreiteter Shells wie die Bash, zsh und tcsh konfigurieren. Was mit Bashish möglich ist, wird bei den Screenshots sehr gut veranschaulicht.
-
10.12.2007 / 23:20
Übrigens lassen sich aus Umgebungsvariablen heraus auch Shellscripts ausführen. Akkustand, CPU-Last deines Servers, die Möglichkeiten sind beinahe unendlich.
:D
-
11.12.2007 / 8:41
Toller Beitrag. Bin erst letztens auf [pimp my shell] gestoßen, deshalb auch jetzt erst ein Kommentar von mir ;-)
Zu Skripten in Umgebungsvariablen: Mein Prompt enthält einen PWD Test, die einen Zeilentrenner einfügt, wenn der Aktuelle Pfad mal zu lang (40 Zeichen) geworden ist. Dazu mag ich es rot, gelb grün:
RED=’\[33[0;91m\]‘
YELLOW=’\[33[0;93m\]‘
GREEN=’\[33[0;32m\]‘
NC=’\[33[0m\]‘
PWDTEST=’if [ ${#PWD} -gt 40 ];then echo -e “\n>”;else echo -e “>”;fi’
export PS1=”$RED\u$NC@$YELLOW\h$NC:$GREEN\w$NC\$($PWDTEST) ”Gruß
Christian -
11.12.2007 / 9:05
Bei der zsh sieht das ganze etwas anders aus. Ich hab zwar die einzelnen Details von dem Beitrag nicht ausprobiert, weiß aber noch von meinen eigenen Versuchen, dass man alle Farben im Prompt in “%{%}” stehen müssen. Bei mir sieht das Ganze dann so aus:
export PS1=$’%{\e[1;32m%}[%D{%H:%M}] %n@%m %{\e[1;34m%}%(5~,%-2~...%2c,%4c) #%{\e[0;0m%} '
Das ergibt den Prompt "[17:42] user@host pfad # ” mit ein paar Farben. Das Interessante daran ist noch, dass der Pfad maximal 4 Elemente enthält. Sollte $PWD doch etwas tiefer im Dateisystembaum sein, werden die ersten und die letzten beiden Elemente angezeigt und durch “…” getrennt.
Die zsh kennt außerdem die Variable RPS1 (right prompt). Mit
export RPS1=$’%{\e[1;31m%}%?%{\e[0;0m%}’
erhält man an der rechten Seite den Rückgabewert des letzten Befehls in rot.
Diese Zeilen habe ich in der zsh-Konfiguration von grml (http://grml.org) und bei einem Shelltools-Vortrag von Sven Guckes gefunden.
Gruß
Karsten -
11.12.2007 / 14:12
@Karsten: Farben gehen in der zsh sehr viel einfacher:
Füge einfach in die .zshrc ‘autoload -U colors && colors’ ein. Ab dann kann man per $fg_bold[green] $fg_no_bold[white] $bg_no_bold[yellow] etc. das Prompt farbig gestalten. -
11.12.2007 / 19:26
Danke für eure Kommentare.
Ich habe mal ein Paar böse Fehler im Artikel behoben, WordPress hatte einige Backslashes verschluckt.
-
12.12.2007 / 9:38
Ein Liebling von mir:
export PS1="\\[\\e]0;\\w\\a\\]\\n\\[\\e[32m\\]\\u@\\h \[33[0;36m\](\\t) \\[\\e[33m\\]\\w\\[\\e[0m\\]\\n\\\$ "
-
13.12.2007 / 9:24
Wie Jeremy erwähnt hat, kann man im Prompt auch Kommandos ausführen. Seit einiger Zeit nutze ich diese Möglichkeit indem ich mir den Rückgabewert ($?) des letzten Befehls anzeigen lasse (falls dieser nicht 0 ist).
folgende Funktion in der .bashrc (vor der Zuweisung des PS1) einfügen:
function returncode {
returncode=$?
if [ $returncode -ne 0 ] ; then
echo "$returncode"
fi
}
Weiter unten in der .bashrc dann den PS1 zuweisen. Zum Beispiel so:
PS1='33[01;31m$(returncode)33[00m\n33[01;31m33[00m\n \$ '
… und endlich keine ‘echo $?’ mehr :-)
-
13.12.2007 / 9:27
naja, da hat die Blog-Software wohl ein paar Backslashes und so gefressen … aber das Wesentliche der PS1-Zuweisung kann man immer noch sehen: $(returncode)
-
13.12.2007 / 22:40
und noch ein Nachtrag:
Die returncode-Funktion stammt übrigens von hermann-uwe.de -
14.12.2007 / 14:17
@meillo: Danke für den Tipp.
(Warum kommt auf so etwas auch nie von alleine?)
-
17.12.2007 / 16:40
Das mit der returncode-Funktion des Prompts geht auch ganz elegant in der zsh:
PS1=$'%{\e[0;33m%}%(?..(%?%))%{\e[0;37m%}%n%{\e[0;31m%}@%{\e[0;33m%}%m%{\e[0m%}%{\e[0;31m%}%#%{\e[0m%}'
Etwas lang, aber braucht keine extra Funktion [zusammengefrickelt mit Hilfe des Buchs: From Bash to Z Shell von Oliver KIddle. Jerry Peek und Peter Stephenson] -
23.2.2008 / 20:22
Schönger Beitrag,
evtl. sollte man noch hinzufügen/ abändern, dass bei: “unset PS1″ kein Dollarzeichen vor der Variable stehen darf.
Ansonsten gibt’s ne “unset: not a valid identifier” Fehlermeldung. -
2.7.2010 / 18:42
[...] Prompt bauen möchte oder schlicht einfach verstehen will, was hier gemacht wird, dem sein pimp my shell ans Herz gelegt. Es gibt dann auch noch Informationen von IBM und Ring of [...]
-
21.7.2010 / 17:27
Thank you for sharing I wish I could go somwhere.
-
3.6.2011 / 13:55
[...] Pimy my Shell, Shellprompt-Konfiguration (bash), Bash Prompt: HOWTO – 6.1 Colours Share [...]
Hinterlasse einen Kommentar
XHTML: Folgende Tags sind erlaubt: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
navigation
- [1] was ist [ pimp my shell ] ?
- [2] programme
- [3] skripte / dotfiles
- [4] shellshots
- [5] mitmachen
- [6] autoren
- [7] einloggen
- [8] impressum
aussehen
ältere beiträge
- 08.26 lsr – Das fehlende Listing
- 06.18 wirklich? so einfach?
- 06.17 fbcmd – update
- 06.04 worklog – die zeit im griff
- 05.30 google-reader >> snownews
- 05.28 fbcmd – facebook in der shell
- 05.28 bitlbee – alles in einem!
- 05.16 NoPaste/pastebin-Service über die Shell mit curl und sprunge.us
- 04.15 Die Heirloom-Tools – Unix unter Linux
- 02.13 dvtm – dwm für die Konsole
beitrags-archiv
- August 2010 (1)
- Juni 2010 (3)
- Mai 2010 (3)
- Mai 2008 (1)
- April 2008 (1)
- Februar 2008 (4)
- Januar 2008 (1)
- Dezember 2007 (2)
- September 2007 (1)
- August 2007 (1)
- Juli 2007 (6)
- Juni 2007 (1)
kategorien
- allgemein (17)
- berichte (7)
- fun (2)
- gnu_screen (2)
- hintergrundwissen (3)
- how-tos (11)
- internes (6)
- programme (31)
- shells (6)
- tutorials (6)
- user-skripte (2)
- vim (5)
- webseiten (5)
15 Kommentare
Zum Kommentarformular | Kommentar rss [?] | trackback uri [?]