Beim Betrachten von diesem fantastischen Thread habe ich festgestellt, dass einige Beispiele verwendet werden
PS1="Blah Blah Blah"
und einige nutzen
Prompt_COMMAND="Blah Blah Blah"
(und einige verwenden beide), wenn Sie die Eingabeaufforderung in einer Bash-Shell festlegen. Was ist der Unterschied zwischen den beiden? Eine SO - Suche und sogar eine etwas breitere Google-Suche bringt mir keine Ergebnisse, so dass selbst ein Link zum richtigen Ort, um nach der Antwort zu suchen, dankbar wäre.
Auf der Bash-Dokumentseite GNU: http://www.gnu.org/software/bash/manual/bashref.html
Prompt_COMMAND
If set, the value is interpreted as a command to execute before
the printing of each primary Prompt ($PS1).
Ich habe es nie benutzt, aber ich hätte es auch wieder benutzen können, wenn ich nur Sh hatte.
Prompt_COMMAND kann gewöhnliche Bash-Anweisungen enthalten, während die PS1-Variable auch Sonderzeichen enthalten kann, z. B. '\ h' für den Hostnamen in der Variablen.
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 Beendigungsstatus des letzten Ausführungsprozesses, 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 den Fehlercode des letzten Programms, das ich im Terminal ausgeführt habe. Beachten Sie das äußere ', das den gesamten Prompt_COMMAND-Ausdruck umgibt. Sie 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\[email protected]\h $BLUE\W $CYAN$BRANCH$RED$ERRMSG \$ $LIGHT_GRAY";'
Die Beispielausgabe sieht in einem Nicht-Git-Verzeichnis folgendermaßen aus:
[email protected] Documents $ false
[email protected] Documents 1 $
und in einem Git-Verzeichnis sehen Sie den Filialnamen:
[email protected] rework mybranch $
Nachdem ich die Kommentare und Bobs Antwort gelesen habe, denke ich, dass es besser ist, es so zu schreiben, wie er es beschreibt. Es ist wartungsfähiger als das, was ich oben geschrieben habe, wo die PS1-Variable innerhalb von Prompt_COMMAND festgelegt ist, die selbst ein sehr komplizierter String ist, der 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 etwa 10 Jahren für mich geschrieben und es hat funktioniert und nicht viel darüber nachgedacht.
Für diejenigen, die wissen wollen, wie ich meine Dinge geändert habe, habe ich den Code für Prompt_COMMAND in einer separaten Datei (wie von Bob beschrieben) eingefügt und dann den String wiedergegeben, den ich als PS1 verwenden möchte:
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}\[email protected]\h${SCHROOT_CHROOT_NAME}${BLUE}\w \
${CYAN}${BRANCH}${RED}${ERRMSG} \$ $RESTORE"
und in meiner .bashrc
function Prompt_command {
RET=$?
export PS1=$(~/.bash_Prompt_command $RET)
}
Prompt_DIRTRIM=3
export Prompt_COMMAND=Prompt_command
Der Unterschied besteht darin, dass PS1 der tatsächlich verwendete Prompt-String ist und Prompt_COMMAND ein Befehl ist, der unmittelbar vor dem Prompt ausgeführt wird. Wenn Sie die einfachste und flexibelste Methode zum Erstellen einer Eingabeaufforderung wünschen, versuchen Sie Folgendes:
Fügen Sie dies in Ihre .bashrc ein:
function Prompt_command {
export PS1=$(~/bin/bash_Prompt)
}
export Prompt_COMMAND=Prompt_command
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 viel einfacher, IMO, da Sie nicht die etwas barocke Substitutionssprache lernen müssen, die nur für die PS1-Variable entwickelt wurde.
Sie denken vielleicht, dass Sie dasselbe tun könnten, indem Sie Prompt_COMMAND direkt auf ~/bin/bash_Prompt setzen und PS1 auf die leere Zeichenfolge setzen. Dies scheint auf den ersten Blick zu funktionieren, aber Sie stellen bald fest, dass der readline-Code erwartet, dass PS1 auf die eigentliche Eingabeaufforderung gesetzt wird. Diese Problemumgehung bewirkt, dass PS1 immer die letzte Eingabeaufforderung widerspiegelt (da die Funktion die tatsächliche PS1 festlegt, die von der aufrufenden Instanz der Shell verwendet wird). Dadurch wird die Funktion von readline und command history problemlos ausgeführt.
Von man bash
:
Prompt_COMMAND
Wenn festgelegt, wird der Wert vor der Ausgabe jeder primären Eingabeaufforderung als Befehl ausgeführt.
PS1
Der Wert dieses Parameters wird erweitert (siehe PROMPTING weiter unten) und als primäre Aufforderungszeichenfolge verwendet. Der Standardwert ist ''\s-\v\$ ''.
Wenn Sie einfach die Eingabeaufforderungszeichenfolge festlegen möchten, genügt die Verwendung von PS1
alleine:
PS1='user \u on Host \h$ '
Wenn Sie unmittelbar vor dem Ausdrucken der Eingabeaufforderung etwas anderes tun möchten, verwenden Sie Prompt_COMMAND
. Wenn Sie zwischengespeicherte Schreibvorgänge mit der Festplatte synchronisieren möchten, können Sie beispielsweise Folgendes schreiben:
Prompt_COMMAND='sync'
Ja, um das wirklich festzunageln:
Prompt_COMMAND
ist eine praktische bash convenience-VariableFunktion, aber es gibt streng genommen nichts, was nicht auch mit PS1
alleine gemacht werden kann, richtig?Ich meine, wenn man/- setze eine andere Variable mit Gültigkeitsbereich außerhalb der Eingabeaufforderung: Abhängig von der Shell müsste diese Variable wahrscheinlich zuerst außerhalb von $PS1
deklariert werden oder (im schlimmsten Fall) um Lust auf etwas zu bekommen, das auf einem FIFO wartet, bevor $PS1
angerufen wird (und am Ende von $PS1
wieder scharf geschaltet wird); Der \u
\h
kann zu Problemen führen, insbesondere wenn Sie ausgefallene reguläre Ausdrücke verwenden. aber ansonsten: kann man alles erreichen, was Prompt_COMMAND
kann, indem man die Befehlssubstitution innerhalb von $PS1
verwendet (und in Eckfällen explizite Subshells)?
Recht?
der Unterschied ist das
Prompt_COMMAND
ausgeben, wird Ihre Bash-Eingabeaufforderung verschraubtPS1
ersetzt \H
und FreundePrompt_COMMAND
führt den Inhalt aus, PS1
verwendet den Inhalt als Eingabeaufforderung.PS1
führt an jeder Eingabeaufforderung die Variablenerweiterung und den Befehlssatz aus. Sie müssen Prompt_COMMAND
nicht verwenden, um PS1
einen Wert zuzuweisen oder beliebigen Code auszuführen. Sie können export PS1='$(uuidgen) $RANDOM'
einfach in .bash_profile
ausführen, verwenden Sie einfach einfache Anführungszeichen