[Logo]

Bash-Prompt

Donnerstag, November 19th, 2009

Mal ein neuer Post zu praktischen Bash-Prompts, nachdem ich den alten doch wieder um einiges überarbeitet habe.

Ziele:

  • Übersichtlichkeit
  • Möglichst lange Eingabezeilen ohne Umbruch
  • Prompt soll auf verschiedenen Hosts unterscheidbar sein
  • Der Prompt soll möglichst informativ sein.

Lösung:

  • Zweizeiliger Prompt, eine Zeile mit vielen Informationen, eine mit nur einem > und der Eingabe dahinter.
  • Username und Hostname Farbkodiert, geschieht automatisch ueber eine Hashing-Funktion
  • Zeitausgabe ermöglicht es einfach zu sehen wann der Befehl beendet wurde, und damit auch wie lange er gebraucht hat.
  • Smiley in der Ausgabe zeigt ob der Befehl korrekt gelaufen ist (Return Code 0 = kein Fehler)

Um Farben aus hostname/username zu generieren, kann man einfach md5sum als hash-Funktion nutzen, und dann das erste Byte der md5summe ansehen. Das tut die Funktion hashcolor in meiner .bashrc. Dabei habe ich mir noch die Freiheit genommen, die Farben so zu sortieren, dass der Text  “root” eine Rote Farbe bekommt.

die Umgebungsvariable PROMPT_COMMAND darf einen Befehl enthalten, der ist in dem Falle die Funktion Prompt, welche auf der Linux-Konsole nur setps1 aufruft um den Prompt zu ändern, und in X-Terminals aber auch settitle und mittels Escape-Code den Titel des Fensters auf das letzte genutzte Kommando zu setyen.

Der Prompt sieht bei mir jetzt so aus:

12:59:56 :-) username@hostname:~

>

Die .bashrc dazu:

# If running interactively, then:
if [ "$PS1" ]; then
    ## aendert den xterm-Titel in das zuletzt benutzte Kommando usw.
    xtitle() {
        echo -ne "\033]0;[$(history 1 | cut -b 8-30)] $USER@$HOSTNAME:$PWD\007";
    }
    setps1() {
        if [ $? -eq 0 ];then smiley=":-)"; else smiley=":-(";fi
        export PS1="\t $smiley \[`hashcolor $USER`\]\u\[$grey\]@\[`hashcolor $HOSTNAME`\]\H\[$grey\]:\[$yellow\]\w\n\[$normal\]> "
    }
    if [ "${TERM}" != "linux" ]; then
        prompt() {
            setps1
            xtitle
        }
    else
        prompt() {
            setps1
        }
    fi
    PROMPT_COMMAND='prompt'
fi

normal='\e[0m'
black='\e[0;30m'
bblack='\e[1;30m'
red='\e[0;31m'
bred='\e[1;31m'
green='\e[0;32m'
bgreen='\e[1;32m'
yellow='\e[0;33m'
byellow='\e[1;33m'
blue='\e[0;34m'
bblue='\e[1;34m'
purple='\e[0;35m'
bpurple='\e[1;35m'
blue2='\e[0;36m'
bblue2='\e[1;36m'
white='\e[0;37m'
bwhite='\e[1;37m'
grey='\e[0;39m'
bgrey='\e[1;39m'

bgnorm='\e[0;0m'
bgblack='\e[0;40m'
bgred='\e[0;41m'
bggreen='\e[0;42m'
bgyellow='\e[0;43m'
bgblue='\e[0;44m'
bgpurple='\e[0;45m'
bgblue2='\e[0;46m'
bggrey='\e[0;47m'

function hashcolor {
    case $(echo $1|md5sum|cut -b 1) in
        0)echo -en $red;;
        1)echo -en $bblue;;
        2)echo -en $green;;
        3)echo -en $bgrey;;
        4)echo -en $yellow;;
        5)echo -en $byellow;;
        6)echo -en $blue;;
        7)echo -en $bred;;
        8)echo -en $purple;;
        9)echo -en $bpurple;;
        a)echo -en $blue2;;
        b)echo -en $bblue2;;
        c)echo -en $grey;;
        d)echo -en $bgreen;;
        e)echo -en $white;;
        f)echo -en $bwhite;;
    esac
}

Die interessanten Manpages zu dem Thema sind:

  • man console_codes erklärt die Escape Codes z.B. für Farben oder auch um den Titel eines X-Terminals zu ändern.
  • man bash erklärt, dass man Farbcodes in \[...\] einschliessen sollte, damit sie den Zeilenumbruch im Prompt nicht kaputt machen.

Geschäftsidee für Lidl

Mittwoch, April 9th, 2008

<nordkurve1900> ich hab ne super geschäftsidee für LIDL
<Steve> lol die wäre?

<nordkurve1900> die könnten hinter den Kassen son Stand machen, wo du Fotos und Videos kaufen kannst, wie du einkaufst.
So wie auf der Wildwasserbahn im Vergnügungspark... Das ist ne Goldgrube...
<Steve>loool xD

(ibash #5054)

Tipp: (Bash-)Prompt verändern

Donnerstag, Oktober 4th, 2007

IBM hat einen guten Artikel zum Thema Prompt magic.

Oft sieht die Bash langweilig so aus:

user@host:/usr/bin$ echo $PS1
\u@\h:\w$

Das frisst bei langen Pfaden natürlich Platz:

user@host:/usr/share/doc/xserver-xorg-video-voodoo$

praktisch ist es da, \W statt \w zu verwenden:

user@host:xserver-xorg-video-voodoo$ ls

Farben erleichtern natürlich den Überblick, bis vor kurzem hab ich quasi den Gentoo Prompt genutzt:

host xserver-xorg-video-voodoo $ echo $PS1
\[\e[01;32m\]\h \[\e[01;34m\]\W $ \[\e[00m\]

Nett ist aber auch der Tipp von der IBM-Seite, den Prompt minimal zu halten, und alle Informationen in die xterm-Titlezeile zu verlagern. Sieht dann so aus:

> echo $PS1
\[\e]2;\u@\H \w\a\e[32;1m\]> \[\e[0m

Wer mag kann auch gleich die Schriftfarbe ändern:

> echo $PS1
\[\e]2;\u@\H \w\a\e[32;1m\]>\[\e[0m\e[32;40m\]

Um die Titelinformationen auf der Linux-Konsole im Prompt zu haben, nimmt man in der .bashrc diese Abfrage:

if [ "$TERM" == "linux" ];then
export PS1=”\u@\H \w\a\e[32;1m\]>\[\e[0m\e[32;40m\] ”
else
export PS1=”\[\e]2;\u@\H \w\a\e[32;1m\]>\[\e[0m\e[32;40m\] ”
fi

Und wer findet dass die ganzen Escape-Codes unschön aussehen kann sich hier bedienen:

esc=’\033['

black=$esc'30m'
bblack=$esc'1;30m'
red=$esc'0;31m'
bred=$esc'1;31m'
green=$esc'0;32m'
bgreen=$esc'1;32m'
yellow=$esc'0;33m'
byellow=$esc'1;33m'
blue=$esc'0;34m'
bblue=$esc'1;34m'
purple=$esc'0;35m'
bpurple=$esc'1;35m'
blue2=$esc'0;36m'
bblue2=$esc'1;36m'
white=$esc'0;37m'
bwhite=$esc'1;37m'
grey=$esc'0;39m'
bgrey=$esc'1;39m'

bgnorm=$esc'XXm'
bgblack=$esc'40m'
bgred=$esc'41m'
bggreen=$esc'42m'
bgyellow=$esc'43m'
bgblue=$esc'44m'
bgpurple=$esc'45m'
bgblue2=$esc'46m'
bggrey=$esc'47m'

Beispiel:

> echo -e $bred"Warnung"
Warnung

Alle Escape-Codes und eine schöne Farbtabelle findet man in dem IBM-Artikel.

Eine weitere interessante Anwendung sind Scripte im Prompt. so kann man z.B. testen ob ein Programm erfolgreich durchgelaufen ist:

$ PS1=':`[ $? -eq 0 ] && echo “)”||echo “(“`’
:) false
:( true
:)

Dabei entspricht der Smiley jeweils dem Exitstatus des letzten Programms (0 = erfolgreich). Das lässt sich natürlich nach belieben kombinieren z.B. mit Farben.

In den xterm-Titel kann man auch automatisch den letzten Befehl reinschreiben lassen:

if [ ${TERM} == "rxvt-unicode" ]; then
xtitle() { echo -ne “\033]0;$1 $USER@$HOSTNAME:$PWD\007″; }
trap ‘xtitle “[$(history 1 | cut -b 8-30)]“‘ DEBUG
fi

Wobei hier vorher noch abgefragt wird, ob es sich auch um ein kompatibles Terminal (hier: urxvt) handelt.

Links: