web-dev-qa-db-de.com

Bash Prompt mit Last Exit Code

Ich habe also versucht, per Bash Prompt so anzupassen, dass es so aussieht

[[email protected] ~]$ _

mit farben. Ich habe es geschafft, konstante Farben zu erhalten (dieselben Farben jedes Mal, wenn ich die Aufforderung sehe), aber ich möchte, dass der Benutzername ('feralin') rot anstatt grün erscheint, wenn der letzte Befehl einen Nicht-Null-Exit-Status hatte. Ich hatte die Idee dass:

\e[1;33m[$(if [[ $? == 0  ]]; then echo "\e[0;31m"; else echo "\e[0;32m"; fi)\u\e[[email protected]\e[1;34m\h \e[0;35m\W\e[1;33m]$ \e[m

Nach meinen Beobachtungen scheint die $(if ...; fi) jedoch einmal ausgewertet zu werden, wenn der .bashrc ausgeführt wird, und das Ergebnis wird für immer ersetzt. Dadurch wird der Name immer grün, auch wenn der letzte Beendigungscode ungleich Null ist (wie in echo $?). Ist das was passiert? Oder ist es einfach etwas anderes an meiner Eingabeaufforderung? Lange Frage kurz, Wie erhalte ich meine Aufforderung, den letzten Beendigungscode zu verwenden?

48
feralin

Wenn Sie anfangen, an eine komplexe PS1 angrenzt, sollten Sie möglicherweise Prompt_COMMAND verwenden.
Damit legen Sie eine Funktion fest, die nach jedem Befehl ausgeführt wird, um die Eingabeaufforderung zu generieren.

Sie könnten Folgendes in Ihrem ~/.bashrc versuchen

Prompt_COMMAND=__Prompt_command # Func to gen PS1 after CMDs

__Prompt_command() {
    local EXIT="$?"             # This needs to be first
    PS1=""

    local RCol='\[\e[0m\]'

    local Red='\[\e[0;31m\]'
    local Gre='\[\e[0;32m\]'
    local BYel='\[\e[1;33m\]'
    local BBlu='\[\e[1;34m\]'
    local Pur='\[\e[0;35m\]'

    if [ $EXIT != 0 ]; then
        PS1+="${Red}\u${RCol}"      # Add red if exit code non 0
    else
        PS1+="${Gre}\u${RCol}"
    fi

    PS1+="${RCol}@${BBlu}\h ${Pur}\W${BYel}$ ${RCol}"
}

Dies sollte das tun, was es klingt, was Sie wollen. Sieh dir die Unter-Datei meiner Bashrc an , wenn du all die Dinge sehen willst, die ich mit meiner __Prompt_command-Funktion mache.

83
demure

Wenn Sie den Befehl Aufforderung nicht verwenden möchten, müssen Sie zwei Dinge beachten:

  1. den Wert von $ erhalten? vor allem anderen, sonst wird es außer Kraft gesetzt
  2. eskappen aller $ in der PS1 (damit es nicht ausgewertet wird, wenn Sie es zuweisen)

Arbeitsbeispiel mit einer Variablen

PS1="\$(VALU="\$?" ; echo \$VALU ; date ; if [ \$VALU == 0 ]; then echo zero; else echo nonzero; fi) " 

Arbeitsbeispiel ohne Variable

Hier muss das if das allererste sein, vor jedem Befehl, der den $? überschreiben würde.

PS1="\$(if [ \$? == 0 ]; then echo zero; else echo nonzero; fi) "

Beachten Sie, wie die \$()-Anweisung escape ist, sodass sie nicht sofort ausgeführt wird, sondern jedes Mal, wenn PS1 verwendet wird. Auch alle Verwendungen von \$?

11
helios

Ich wollte die Standardfarben von Debian beibehalten, den genauen Code drucken und nur bei einem Fehler drucken:

# Show exit status on failure.
Prompt_COMMAND=__Prompt_command

__Prompt_command() {
    local curr_exit="$?"

    local BRed='\[\e[0;91m\]'
    local RCol='\[\e[0m\]'

    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\[email protected]\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '

    if [ "$curr_exit" != 0 ]; then
        PS1="[${BRed}$curr_exit${RCol}]$PS1"
    fi
}
3
Velkan

@Demure verbessert

Ich denke, das ist wichtig, da der Exit-Status nicht immer 0 oder 1 ist.

if [ $EXIT != 0 ]; then
    PS1+="${Red}${EXIT}:\u${RCol}"      # Add red if exit code != 0
else
    PS1+="${Gre}${EXIT}:\u${RCol}"      # Also displays exit status
fi
0
user1340624