2010-06-17 28 views
74

Während Sie einen Blick auf this awesome thread unter bemerkte ich, dass einige BeispieleWas ist der Unterschied zwischen PS1 und PROMPT_COMMAND ist

PS1="Blah Blah Blah" 

und einige Verwendung

PROMPT_COMMAND="Blah Blah Blah" 

(und einige verwenden beide) bei der Einstellung der Eingabeaufforderung verwenden in einer Bash-Shell. Was ist der Unterschied zwischen den beiden? Eine SO-Suche und sogar ein bisschen breiteres Google-Suchen bringen mir keine Ergebnisse, so dass selbst ein Link zum richtigen Ort, um nach der Antwort zu suchen, geschätzt würde. Vielen Dank!

Antwort

39

Von der GNU Bash doc Seite: 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 es nie benutzt, aber ich konnte diese wieder verwendet haben, wenn ich nur sh hatte.

53

PROMPT_COMMAND kann normale Bash-Anweisungen enthalten, während die PS1-Variable auch die Sonderzeichen wie '\ h' für Hostname in der Variablen enthalten kann.

Zum Beispiel hier ist meine Bash-Eingabeaufforderung, die sowohl PROMPT_COMMAND und PS1 verwendet. Der bash-Code in PROMPT_COMMAND ermittelt, in welcher git-Verzweigung Sie sich befinden, und zeigt ihn an der Eingabeaufforderung zusammen mit dem Beendigungsstatus des letzten Ausführungsprozesses, dem Hostnamen und dem Basisnamen von 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 der Fehlercode des letzten Programms, das ich im Terminal ausgeführt habe. Beachten Sie, dass der äußere Ausdruck den gesamten PROMPT_COMMAND-Ausdruck umgibt. Es enthält PS1, so dass 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";' 

Beispiel Ausgabe sieht wie folgt in einem nicht-Git-Verzeichnis:

[email protected] Documents $ false 
[email protected] Documents 1 $ 

und in einem Git-Verzeichnis, das Sie den Zweig Namen:

[email protected] rework mybranch $ 
+1

Sie können eine Ihrer Zeilen verkürzen: 'if git branch &>/dev/null; dann \ '. Es leitet sowohl stdout als auch stderr nach/dev/null um. http://www.tldp.org/LDP/abs/html/io-redirection.html –

+2

Es besteht keine Notwendigkeit, * 'PROMPT_COMMAND' zu exportieren. – dolmen

+2

Ich denke, dass der Kommentar von ceving auch für diese Antwort sehr zutreffend ist: 'Setze PS1 nicht in PROMPT_COMMAND! Setze Variablen in PROMPT_COMMAND und verwende sie in PS1' – Blauhirn

39

Der Unterschied besteht darin, dass PS1 die tatsächliche Eingabeaufforderungszeichenfolge und PROMPT_COMMAND ist ein Befehl, der unmittelbar vor der Eingabeaufforderung ausgeführt wird. Wenn Sie die einfachste und flexibelste Methode zum Aufbau einer Eingabeaufforderung wollen, versuchen Sie dies:

Setzen Sie diese in Ihre .bashrc:

function prompt_command { 
    export PS1=$(~/bin/bash_prompt) 
} 
export PROMPT_COMMAND=prompt_command 

Dann ein Skript schreiben (bash, perl, Rubin: Wahl), und platziere es in ~/bin/bash_prompt.

Das Skript kann beliebige Informationen verwenden, um eine Eingabeaufforderung zu erstellen. Dies ist IMO viel einfacher, weil Sie die etwas barocke Ersatzsprache, die nur für die PS1-Variable entwickelt wurde, nicht lernen müssen.

Sie könnten denken, dass Sie dasselbe tun könnten, indem Sie einfach PROMPT_COMMAND direkt auf ~/bin/bash_prompt setzen und PS1 auf die leere Zeichenfolge setzen. Das 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 in der Historie Backwards scrollen, werden die Dinge dadurch durcheinander gebracht. Diese Problemumgehung verursacht, dass PS1 immer die letzte Eingabeaufforderung widerspiegelt (da die Funktion die tatsächliche PS1, die von der aufrufenden Instanz der Shell verwendet wird, festlegt), und dies bewirkt, dass die Readline und der Befehlshistorie funktionieren.

+6

Setze 'PS1' nicht in' PROMPT_COMMAND'! Setze Variablen in 'PROMPT_COMMAND' und verwende sie in' PS1'. Andernfalls werden Sie die Möglichkeit verlieren, die 'PS1'-Escape-Sequenzen wie' \ u' oder '\ h' zu verwenden. Sie müssen sie in 'PROMPT_COMMAND' neu erfinden. Das ist möglich, aber es ist nicht möglich, das Verlieren von "\" und "\" zu umgehen, die den Anfang und das Ende von nicht druckbaren Zeichen markieren. Dies bedeutet, dass Sie Farben nicht verwenden können, ohne das Terminal über die Länge der Eingabeaufforderung zu verwirren. Und dies verwirrt 'readline' beim Editieren eines Befehls, der zwei Zeilen erzeugt. Am Ende hast du ein großes Durcheinander auf dem Bildschirm. – ceving

+0

@ceving Wahr, dass! Man kann PROMPT_COMMAND verwenden, um das ** Format ** Ihrer PS1 zu ändern und das Beste aus beiden Welten zu erhalten. – cvsguimaraes

+3

'PROMPT_COMMAND' wird ausgeführt, bevor' PS1' gedruckt wird. Ich sehe keine Probleme, 'PS1' aus 'PROMPT_COMMAND' zu setzen, denn nachdem' PROMPT_COMMAND' beendet ist, wird die Shell 'PS1' ausgeben, die von' PROMPT_COMMAND' (oder in diesem Fall innerhalb von 'prompt_command') modifiziert wurde? –

7

Von man bash:

PROMPT_COMMAND

Wenn gesetzt, wird der Wert als ein Befehl ausgeführt vor jeder primären Aufforderung ausgibt. und als die primäre Eingabeaufforderungs-Zeichenfolge

PS1

Der Wert dieses Parameters wird (PROMPTING siehe unten) erweitert. Der Standardwert ist '' \ s- \ v \ $ ''.

Wenn Sie wollen einfach nur die Eingabeaufforderung Zeichenfolge setzen, ist PS1 allein mit genug:

PS1='user \u on host \h$ ' 

Wenn Sie nur etwas anderes zu tun, bevor Sie die Prompts, PROMPT_COMMAND verwenden. Wenn Sie z. B. zwischengespeicherte Schreibvorgänge auf Festplatte synchronisieren möchten, können Sie Folgendes schreiben:

PROMPT_COMMAND='sync' 
+1

Sie können auch den Titel des Terminals von 'PS1' setzen, ohne' PROMPT_COMMAND' zu benötigen Die Reihenfolge, in der der Titel gesetzt wird, kann in 'PS1' enthalten sein, das mit' \ '' und '\' 'umhüllt ist. – dolmen

+1

@dolmen Alles in Ordnung. Dann lassen Sie uns etwas anderes tun, etwa das dynamische Setzen einer Umgebungsvariablen. – Cyker

Verwandte Themen