^ C causa PROMPT = '$ (my_prompt_function)' per non essere mai chiamato


2

Sto cercando di eseguire una funzione più complessa che costruisce la stringa PROMPT in ZSH e, in circostanze normali, funziona. Tuttavia, poiché ho il seguente TRAPINT per stampare "^ C" quando invio SIGINT al prompt, non funziona (non chiama la mia funzione).

.zshrc

TRAPINT() {
    print -n "^C"
    return $(( 128 + $1 ))
}
my_prompt_function() {
    echo '>'
}
setopt PROMPT_SUBST
PROMPT='$(my_prompt_function)'

Tuttavia, se premo ^Cal prompt, si blocca semplicemente:

>
>^C
# ...hangs here until I press <Enter>

Come faccio a sapere, all'interno di TRAPINT, che sono al prompt, rispetto a un programma in esecuzione, in modo da non poter restituire un errore?

Risposte:


1

Sembra che la sostituzione del comando non sia valutata dopo che la shell è stata interrotta in quel modo.

Puoi aggirarlo usando il precmdgancio:

precmd () {
    MYPROMPT='>'
}
setopt PROMPT_SUBST
PROMPT='${MYPROMPT}'

precmdviene eseguito prima di ogni prompt. Si noti che precmdnon viene rieseguito nei casi in cui il prompt viene semplicemente ridisegnato senza eseguire una riga di comando (come in questo caso). Funziona ancora come il valore di MYPROMPTrimane anche senza correre precmd.


  • Puoi anche avere più precmdfunzioni. Puoi gestirli con il add-zsh-hookmodulo:

    autoload -Uz add-zsh-hook
    myprompt_function () {
        MYPROMPT='>'
    }
    add-zsh-hook precmd myprompt_function
    setopt PROMPT_SUBST
    PROMPT='${MYPROMPT}'
    
  • È inoltre possibile utilizzare la speciale variabile di matrice psvar, i cui membri sono accessibili con il prompt escape %vo %Nvdove Ndeve essere visualizzato l'indice di matrice:

    precmd () {
        psvar[3]='>'
    }
    PROMPT='%3v'
    

0

Accetto la risposta di Adaephon, ma invio qui per mostrare la mia soluzione finale:

TRAPINT() {
  if [ "$IS_PROMPTING" == true ]; then
    print -n "^C"
    return $(( 128 + $1 ))
  fi
}
precmd() {
  IS_PROMPTING=true
  PROMPT=$(command-that-generates-prompt-string)
}
preexec() {
  IS_PROMPTING=false
}

TRAPINT controlla in modo condizionale se l'utente è al prompt o all'interno di un comando di esecuzione tramite un flag che è impostato in modo appropriato tramite precmd / preexec.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.