2010-06-17 11 views
74

Mentre dare un'occhiata a this awesome thread ho notato che alcuni esempi usanoQual è la differenza tra PS1 e PROMPT_COMMAND

PS1="Blah Blah Blah" 

e un certo uso

PROMPT_COMMAND="Blah Blah Blah" 

(e alcuni usano entrambi) quando si imposta il prompt in una shell bash. Qual è la differenza tra i due? Una ricerca SO e anche una ricerca più ampia su google non mi stanno dando risultati, quindi anche un link al posto giusto per cercare la risposta sarebbe apprezzato. Grazie!

risposta

39

Dalla pagina doc GNU Bash: 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). 

ho mai usato, ma avrei potuto usare questa indietro quando ho avuto solo sh.

53

PROMPT_COMMAND può contenere ordinarie istruzioni bash mentre la variabile PS1 può contenere anche i caratteri speciali, come '\ h' per nomehost, nella variabile.

Ad esempio, ecco il mio prompt di bash che utilizza sia PROMPT_COMMAND che PS1. Il codice bash in PROMPT_COMMAND elabora il ramo git in cui ti trovi e lo visualizza al prompt, insieme allo stato di uscita dell'ultimo processo di esecuzione, nome host e nome di base del pwd. La variabile RET memorizza il valore di ritorno dell'ultimo programma eseguito. Questo è comodo per vedere se c'è stato un errore e il codice di errore dell'ultimo programma che ho eseguito nel terminale. Nota l'esterno 'che circonda l'intera espressione PROMPT_COMMAND. Include PS1 in modo che questa variabile venga rivalutata ogni volta che viene valutata la variabile PROMPT_COMMAND.

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";' 

uscita esempio si presenta in una directory non-git:

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

e in una directory git si vede il nome del ramo:

[email protected] rework mybranch $ 
+1

È possibile abbreviare una delle righe: 'se git branch &>/dev/null; quindi \ '. Reindirizza sia stdout che stderr in/dev/null. http://www.tldp.org/LDP/abs/html/io-redirection.html –

+2

Non è necessario * esportare * 'PROMPT_COMMAND'. – dolmen

+2

Penso che il commento di ceving sia molto vero anche per questa risposta: 'Non impostare PS1 in PROMPT_COMMAND! Imposta le variabili in PROMPT_COMMAND e usale in PS1' – Blauhirn

39

La differenza è che PS1 è la stringa di prompt effettiva utilizzata e PROMPT_COMMAND è un comando che viene eseguito immediatamente prima del prompt. Se si desidera che il modo più semplice più flessibile della costruzione di un prompt, provate questo:

mettere questo nel tuo .bashrc:

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

quindi scrivere uno script (bash, perl, ruby: la vostra scelta), e posizionarlo in ~/bin/bash_prompt.

Lo script può utilizzare qualsiasi informazione a cui piaccia costruire un prompt. Questo è IMO molto più semplice perché non devi imparare il linguaggio di sostituzione un po 'barocco che è stato sviluppato solo per la variabile PS1.

Si potrebbe pensare che si potrebbe fare lo stesso semplicemente impostando PROMPT_COMMAND direttamente su ~/bin/bash_prompt e impostando PS1 sulla stringa vuota. Questo a prima vista sembra funzionare, ma presto si scopre che il codice readline si aspetta che PS1 sia impostato sul prompt effettivo, e quando si fa scorrere il backword nella cronologia, le cose si incasinano di conseguenza. Questa soluzione alternativa fa sì che PS1 rifletta sempre il prompt più recente (poiché la funzione imposta il PS1 effettivo utilizzato dall'istanza di richiamo della shell) e ciò rende la cronologia di readline e dei comandi funzionante.

+6

Non impostare 'PS1' in' PROMPT_COMMAND'! Imposta le variabili in 'PROMPT_COMMAND' e usale in' PS1'. Altrimenti perderai la possibilità di usare le sequenze di escape 'PS1' come' \ u' o '\ h'. Devi reinventarli in 'PROMPT_COMMAND'. Questo potrebbe essere possibile ma non è possibile aggirare la perdita di '\ [' e '\]' che segnano l'inizio e la fine dei caratteri non stampabili. Ciò significa che non puoi usare i colori senza confondere il terminale sulla lunghezza del prompt. E questo confonde 'readline' quando si modifica un comando che genera due righe. Alla fine hai un bel casino sullo schermo. – ceving

+0

@ceving Vero che! Si può usare PROMPT_COMMAND per cambiare il ** formato ** della PS1 e ottenere il meglio da entrambi i mondi – cvsguimaraes

+3

'PROMPT_COMMAND' viene eseguito prima di stampare' PS1'. Non vedo problemi nell'impostare 'PS1' dall'interno di' PROMPT_COMMAND', perché dopo che 'PROMPT_COMMAND' è finito, la shell stamperà' PS1', che è stato modificato da 'PROMPT_COMMAND' (o in questo caso, all'interno di' prompt_command')? –

7

Da man bash:

PROMPT_COMMAND

Se impostato, il valore viene eseguita come un comando prima di emettere il prompt primario.

PS1

Il valore di questo parametro è espanso (vedi PROMPTING avanti) e usato come stringa prompt primario. Il valore predefinito è '' \ s- \ v \ $ ''.

Se si vuole semplicemente impostare la stringa del prompt, usando PS1 da sola è sufficiente:

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

Se si vuole fare qualcosa di diverso poco prima di stampare il prompt, utilizzare PROMPT_COMMAND. Ad esempio, se si desidera sincronizzare le scritture memorizzate nella cache su disco, è possibile scrivere:

PROMPT_COMMAND='sync' 
+1

Puoi anche impostare il titolo del terminale da 'PS1' senza bisogno di' PROMPT_COMMAND', come sequenza che imposta il titolo può essere inclusa in 'PS1' avvolto con' \ ['e' \] '. – dolmen

+1

@dolmen Va bene. Quindi facciamo qualcos'altro, come ad esempio l'impostazione dinamica di una variabile d'ambiente. – Cyker

Problemi correlati