PROMPT_COMMAND kann gewöhnliche Bash-Anweisungen enthalten, während die PS1-Variable auch Sonderzeichen wie '\ h' für den Hostnamen in der Variablen enthalten kann.
Zum Beispiel ist hier meine Bash-Eingabeaufforderung, die sowohl PROMPT_COMMAND als auch PS1 verwendet. Der Bash-Code in PROMPT_COMMAND ermittelt, in welchem Git-Zweig Sie sich möglicherweise befinden, und zeigt diesen an der Eingabeaufforderung zusammen mit dem Exit-Status des zuletzt ausgeführten Prozesses, dem Hostnamen und dem Basisnamen des pwd an. Die Variable RET speichert den Rückgabewert des zuletzt ausgeführten Programms. Dies ist praktisch, um festzustellen, ob ein Fehler aufgetreten ist, und um den Fehlercode des letzten Programms anzuzeigen, das ich im Terminal ausgeführt habe. Beachten Sie das äußere ', das den gesamten PROMPT_COMMAND-Ausdruck umgibt. Es enthält PS1, sodass diese Variable jedes Mal neu ausgewertet wird, wenn die Variable PROMPT_COMMAND ausgewertet wird.
PROMPT_COMMAND='RET=$?;\
BRANCH="";\
ERRMSG="";\
if [[ $RET != 0 ]]; then\
ERRMSG=" $RET";\
fi;\
if git branch &>/dev/null; then\
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2);\
fi;
PS1="$GREEN\u@\h $BLUE\W $CYAN$BRANCH$RED$ERRMSG \$ $LIGHT_GRAY";'
Die Beispielausgabe sieht in einem Nicht-Git-Verzeichnis folgendermaßen aus:
sashan@dhcp-au-122 Documents $ false
sashan@dhcp-au-122 Documents 1 $
und in einem Git-Verzeichnis sehen Sie den Filialnamen:
sashan@dhcp-au-122 rework mybranch $
Aktualisieren
Nachdem ich die Kommentare und Bobs Antwort gelesen habe, denke ich, dass es besser ist, sie so zu schreiben, wie er es beschreibt. Es ist wartbarer als das, was ich ursprünglich oben geschrieben habe, wo die PS1-Variable im PROMPT_COMMAND festgelegt ist, einer super komplizierten Zeichenfolge, die zur Laufzeit von bash ausgewertet wird. Es funktioniert, aber es ist komplizierter als es sein muss. Um fair zu sein, habe ich PROMPT_COMMAND vor ungefähr 10 Jahren für mich selbst geschrieben und es hat funktioniert und ich habe nicht zu viel darüber nachgedacht.
Für diejenigen, die neugierig sind, wie ich meine Sachen geändert habe, habe ich den Code für PROMPT_COMMAND im Grunde genommen in eine separate Datei gestellt (wie von Bob beschrieben) und dann die Zeichenfolge wiedergegeben, die ich als PS1 beabsichtige:
GREEN="\[\033[0;32m\]"
CYAN="\[\033[0;36m\]"
RED="\[\033[0;31m\]"
PURPLE="\[\033[0;35m\]"
BROWN="\[\033[0;33m\]"
LIGHT_GRAY="\[\033[0;37m\]"
LIGHT_BLUE="\[\033[1;34m\]"
LIGHT_GREEN="\[\033[1;32m\]"
LIGHT_CYAN="\[\033[1;36m\]"
LIGHT_RED="\[\033[1;31m\]"
LIGHT_PURPLE="\[\033[1;35m\]"
YELLOW="\[\033[1;33m\]"
WHITE="\[\033[1;37m\]"
RESTORE="\[\033[0m\]" #0m restores to the terminal's default colour
if [ -z $SCHROOT_CHROOT_NAME ]; then
SCHROOT_CHROOT_NAME=" "
fi
BRANCH=""
ERRMSG=""
RET=$1
if [[ $RET != 0 ]]; then
ERRMSG=" $RET"
fi
if which git &>/dev/null; then
BRANCH=$(git branch 2>/dev/null | grep \* | cut -d " " -f 2)
else
BRANCH="(git not installed)"
fi
echo "${GREEN}\u@\h${SCHROOT_CHROOT_NAME}${BLUE}\w \
${CYAN}${BRANCH}${RED}${ERRMSG} \$ $RESTORE"
und in meinem .bashrc
function prompt_command {
RET=$?
export PS1=$(~/.bash_prompt_command $RET)
}
PROMPT_DIRTRIM=3
export PROMPT_COMMAND=prompt_command
if git branch &>/dev/null ; then\
. Es leitet sowohl stdout als auch stderr nach / dev / null um. tldp.org/LDP/abs/html/io-redirection.htmlPROMPT_COMMAND
.Don't set PS1 in PROMPT_COMMAND! Set variables in PROMPT_COMMAND and use them in PS1
PS1
online zu wechselnPROMPT_COMMAND
. Es ist perfekter nützlicher Code. Im Gegensatz zu Bobs Antwort wurde diePS1
Variable korrekt konstruiert. Dies ermöglicht eine viel komplexere Bash-Eingabeaufforderung, abhängig von Ihrer tatsächlichen Situation.PS1
innen hatPROMPT_COMMAND
keinen Zweck. Es ist ein Beispiel, wie man es nicht macht. Wenn SiePS1
einmal konstruiert haben.bash_profile
, verwenden Sie einfach einfache Anführungszeichen anstelle von doppelten Anführungszeichen, damit die Ersetzungen von Variablen bei jeder Eingabeaufforderung ausgewertet werden.Der Unterschied besteht darin, dass PS1 die tatsächlich verwendete Eingabeaufforderungszeichenfolge ist und PROMPT_COMMAND ein Befehl ist, der unmittelbar vor der Eingabeaufforderung ausgeführt wird. Wenn Sie die einfachste und flexibelste Methode zum Erstellen einer Eingabeaufforderung suchen, versuchen Sie Folgendes:
Fügen Sie dies in Ihre .bashrc ein:
Schreiben Sie dann ein Skript (Bash, Perl, Ruby: Ihre Wahl) und platzieren Sie es in ~ / bin / bash_prompt.
Das Skript kann beliebige Informationen verwenden, um eine Eingabeaufforderung zu erstellen. Dies ist IMO viel einfacher, da Sie nicht die etwas barocke Substitutionssprache lernen müssen, die nur für die PS1-Variable entwickelt wurde.
Sie könnten denken, dass Sie dasselbe tun könnten, indem Sie PROMPT_COMMAND einfach direkt auf ~ / bin / bash_prompt setzen und PS1 auf die leere Zeichenfolge setzen. Dies scheint zunächst zu funktionieren, aber Sie werden bald feststellen, dass der Readline-Code erwartet, dass PS1 auf die tatsächliche Eingabeaufforderung gesetzt wird, und wenn Sie im Verlauf durch die Backwords scrollen, werden die Dinge dadurch durcheinander gebracht. Diese Problemumgehung bewirkt, dass PS1 immer die neueste Eingabeaufforderung widerspiegelt (da die Funktion die tatsächliche PS1 festlegt, die von der aufrufenden Instanz der Shell verwendet wird). Dadurch funktionieren Readline- und Befehlsverlauf einwandfrei.
quelle
PS1
inPROMPT_COMMAND
! Setzen Sie Variablen inPROMPT_COMMAND
und verwenden Sie sie inPS1
. Andernfalls verlieren Sie die Möglichkeit, diePS1
Escape-Sequenzen wie\u
oder zu verwenden\h
. Sie müssen sie neu erfindenPROMPT_COMMAND
. Das mag möglich sein, aber es ist nicht möglich, den Verlust von\[
und\]
das Markieren des Anfangs und des Endes von nicht druckbaren Zeichen zu umgehen. Dies bedeutet, dass Sie keine Farben verwenden können, ohne das Terminal über die Länge der Eingabeaufforderung zu verwirren. Und das verwirrtreadline
beim Bearbeiten eines Befehls, der zwei Zeilen erzeugt. Am Ende haben Sie ein großes Durcheinander auf dem Bildschirm.PROMPT_COMMAND
wird vor dem Drucken ausgeführtPS1
. Ich sehe keine Probleme beim EinstellenPS1
von innenPROMPT_COMMAND
, da nachPROMPT_COMMAND
Abschluss der Shell die Shell gedruckt wirdPS1
, die vonPROMPT_COMMAND
(oder in diesem Fall von innenprompt_command
) geändert wurde .export PS1='$(~/bin/bash_prompt)'
verwenden. Das gleiche Problem sieht vernünftig ausVon
man bash
:Wenn Sie einfach die Eingabeaufforderungszeichenfolge festlegen möchten, reicht die Verwendung
PS1
allein aus:Wenn Sie kurz vor dem Drucken der Eingabeaufforderung etwas anderes tun möchten, verwenden Sie
PROMPT_COMMAND
. Wenn Sie beispielsweise zwischengespeicherte Schreibvorgänge auf die Festplatte synchronisieren möchten, können Sie Folgendes schreiben:quelle
PS1
ohne dassPROMPT_COMMAND
, wie die Sequenz, die den Titel festlegen kann in aufgenommen wirdPS1
mit eingewickelt\[
und\]
.PS1
. Sie werden nur in der Unterschale festgelegt, sodass Sie ihren Wert nicht zurückerhalten können. aber Ihr Beispiel ist trivialPS1='$(sync)user \u on host \h$ '
Der Unterschied ist das
PROMPT_COMMAND
, wird Ihre Bash-Eingabeaufforderung beschädigtPS1
Ersatz\H
und FreundePROMPT_COMMAND
führt seinen Inhalt aus,PS1
verwendet seinen Inhalt als Eingabeaufforderung.PS1
Führt an jeder Eingabeaufforderung eine Variablenerweiterung und Befehlssubstitution durch, ohne dass einPROMPT_COMMAND
Wert zugewiesenPS1
oder ein beliebiger Code ausgeführt werden muss. Sie können dies einfachexport PS1='$(uuidgen) $RANDOM'
einmal tun, indem Sie einfach.bash_profile
einfache Anführungszeichen verwendenquelle
Ja, um zu versuchen, das wirklich festzunageln:
PROMPT_COMMAND
ist eine praktische Bash- Convenience-Variable / -Funktion, aber es gibt streng genommen nichts, was nicht auchPS1
alleine gemacht werden kann , richtig?Ich meine, wenn man eine andere Variable mit einem Gültigkeitsbereich außerhalb der Eingabeaufforderung festlegen möchte : Abhängig von der Shell müsste diese Variable wahrscheinlich zuerst außerhalb deklariert werden, oder (im schlimmsten Fall) muss man sich mit etwas auseinandersetzen, das vorher auf ein FIFO wartet anrufen (und am Ende wieder bewaffnet ); das könnte einige Probleme verursachen, besonders wenn Sie einige ausgefallene regex verwenden; aber sonst: kann man alles erreichen, indem man die Befehlssubstitution innerhalb (und vielleicht in Eckfällen explizite Subshells) verwendet?
$PS1
$PS1
$PS1
\u
\h
PROMPT_COMMAND
$PS1
Richtig?
quelle