it-swarm.com.de

Was ist der Unterschied zwischen PS1 und Prompt_COMMAND?

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.

90
Jed Daniels

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.

48
Scott Thomson

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 $ 

Aktualisieren

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
57
sashang

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.

40
Bob

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'
8
Cyker

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?

0
Geoff Nixon

der Unterschied ist das 

  • wenn Sie eine unvollständige Zeile aus Prompt_COMMAND ausgeben, wird Ihre Bash-Eingabeaufforderung verschraubt
  • PS1 ersetzt \H und Freunde
  • Prompt_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

0
pal