2013-02-13 23 views
13

Sto provando a impostare PS1 in modo che stampi qualcosa subito dopo l'accesso, ma preceduto da una nuova riga in seguito.Come impostare una nuova riga condizionale in PS1?

Supponiamo export PS1="\h:\W \u\$ ", quindi prima volta (vale a dire, a destra dopo il login) si ottiene:

hostname:~ username$ 

Ho cercato qualcosa di simile nella mia ~/.bashrc:

function __ps1_newline_login { 
    if [[ -n "${PS1_NEWLINE_LOGIN-}" ]]; then 
    PS1_NEWLINE_LOGIN=true 
    else 
    printf '\n' 
    fi 
} 

export PS1="\$(__ps1_newline_login)\h:\W \u\$ “ 

aspettandosi di ottenere:

# <empty line> 
hostname:~ username$ 

Un esempio completo dall'inizio sarebbe:

hostname:~ username$ ls `# notice: no empty line desired above!` 
Desktop  Documents 

hostname:~ username$ 
+0

Per riferimento, il motivo per cui il comando non funziona è 1) che hai usato le virgolette doppie, e quindi __ps1_newline_login viene eseguito quando si esegue l'esportazione piuttosto che ogni pronta e 2) che se avessi usato le virgolette singole, la funzione sarebbe stata eseguita in una subshell a causa di $ (..) quindi qualsiasi variabile impostata non sarebbe visibile al di fuori di essa –

+0

@thatotherguy grazie mille per questa spiegazione. Mi ha davvero aiutato a capire vari miei problemi. – Ali

+0

@thatotherguy ripensandoci: sei assolutamente sicuro che '__ps1_newline_login' viene eseguito solo una volta, ma non tutte le volte? Ad esempio, '__git_ps1' usa questa stessa identica tecnica per impostare ogni prompt non solo inizialmente. – Ali

risposta

13

provare quanto segue:

function __ps1_newline_login { 
    if [[ -z "${PS1_NEWLINE_LOGIN}" ]]; then 
    PS1_NEWLINE_LOGIN=true 
    else 
    printf '\n' 
    fi 
} 

PROMPT_COMMAND='__ps1_newline_login' 
export PS1="\h:\W \u\$ " 

Spiegazione:

  • PROMPT_COMMAND è una variabile bash speciale che viene eseguito ogni volta prima del prompt è impostata.
  • È necessario utilizzare il flag -z per verificare se la lunghezza di una stringa è 0.
+0

ulteriore foratura su questo argomento: stai implicando che non c'è modo di echeggiare/stampare una nuova riga da una funzione e usarla in 'PS1'? come se lo aveste impostato contenente un '\ n' in primo luogo? – Ali

+0

Non sono sicuro di avere la tua domanda, ma se vuoi il '\ n' in' PS1', puoi semplicemente aggiornare 'PS1' e rimuovere' PROMP_COMMAND' invece di 'printf" '\ n "' – Mark

5

Correndo con la risposta di dogbane, è possibile effettuare PROMPT_COMMAND "autodistruzione", evitando la necessità di eseguire una funzione dopo ogni comando

Nel file .bashrc o .bash_profile, fare

export PS1='\h:\W \u\$ ' 
reset_prompt() { 
    PS1='\n\h:\W \u\$ ' 
} 
PROMPT_COMMAND='((PROMPT_CTR-- < 0)) && { 
    unset PROMPT_COMMAND PROMPT_CTR 
    reset_prompt 
}' 

Quando il file viene elaborato, PS1 inizialmente non visualizza una nuova linea prima del prompt. Tuttavia, PROMPT_CTR viene immediatamente decrementato a -1 (è implicitamente 0 prima) prima che il prompt venga visualizzato la prima volta. Dopo il primo comando, PROMPT_COMMAND cancella se stesso e il contatore prima di reimpostare il prompt per includere la nuova riga. Successivamente, non verrà eseguito PROMPT_COMMAND.

Ovviamente, c'è un mezzo felice, in cui anziché lo PROMPT_COMMAND si deseleziona, si reimposta semplicemente su una funzione più ordinaria. Qualcosa di simile

export PS1='\h:\W \u\$ ' 
normal_prompt_cmd() { 
    ... 
} 
reset_prompt() { 
    PS1='\n\h:\W \u\$ ' 
} 
PROMPT_COMMAND='((PROMPT_CTR-- < 0)) && { 
    PROMPT_COMMAND=normal_prompt_cmd 
    reset_prompt 
    unset PROMPT_CTR 
    }' 
+0

How vuoi 'reset_prompt' nel secondo modulo per favore? Forse sono stato un po 'confuso, devo ammettere. – Ali

+0

Ho aggiornato la risposta. La cosa fondamentale da notare è che puoi cambiare il valore di 'PROMPT_COMMAND' in' PROMPT_COMMAND'; non è realmente ricorsione, dal momento che 'PROMPT_COMMAND' è solo una stringa che contiene un mini-script da eseguire. Una delle cose che lo script potrebbe fare è cambiare il valore di 'PROMPT_COMMAND'. – chepner

+0

perché non semplicemente 'PROMPT_COMMAND =" $ {PROMPT_COMMAND} __ ps1_newline_login; "'? – Ali

1

2018 Aggiornamento (ispirato dalla risposta di chepner)

Modifiche:

  1. No need to export PS1
  2. ho usato "\ n $ PS1" invece di ri-tipizzazione ("$var" inserisce var nella stringa, funziona solo con virgolette doppie).

Immettere quanto segue in ~ /.bash_profile (sostituendo prima linea assieme al prompt):

PS1=YOUR PROMPT HERE (without newline) 

reset_prompt() { 
    PS1="\n$PS1" 
} 
PROMPT_COMMAND='((PROMPT_CTR-- < 0)) && { 
    unset PROMPT_COMMAND PROMPT_CTR 
    reset_prompt 
}' 
+0

Mi piace! – Ali