Risposte:
Controlla se il numero di cronologia è stato incrementato. Un prompt annullato o un prompt in cui l'utente ha appena premuto Enternon incrementa il numero della cronologia.
Il numero di cronologia è disponibile nella variabile HISTCMD
, ma questo non è disponibile in PROMPT_COMMAND
(perché ciò che si desidera è in realtà il numero di cronologia del comando precedente; il comando che si esegue da PROMPT_COMMAND
solo non ha un numero di cronologia). È possibile ottenere il numero dall'output di fc
.
prompt_command () {
HISTCMD_previous=$(fc -l -1); HISTCMD_previous=${HISTCMD_previous%%$'[\t ]'*}
if [[ -z $HISTCMD_before_last ]]; then
# initial prompt
elif [[ $HISTCMD_before_last = "$HISTCMD_previous" ]]; then
# cancelled prompt
else
# a command was run
fi
HISTCMD_before_last=$HISTCMD_previous
}
PROMPT_COMMAND='prompt_command'
Nota che se hai attivato la compressione dei duplicati nella cronologia ( HISTCONTROL=ignoredups
o HISTCONTROL=erasedups
), questo riporterà erroneamente un comando vuoto dopo aver eseguito successivamente due comandi identici.
${HISTCMD_previous%%$'[\t ]'*}
bit mancava $'…'
e alla fine si è troncato dopo `,
t` o spazio anziché dopo tab o spazio, ma bash stampa una scheda.
C'è una soluzione alternativa, ma ha alcuni requisiti:
È necessario impostare $HISTCONTROL
per salvare TUTTI i comandi, anche i duplicati e gli spazi. Quindi impostare:
HISTCONTROL=
Ora definisci una funzione da chiamare come $PROMPT_COMMAND
:
isnewline () {
# read the last history number
prompt_command__isnewline__last="$prompt_command__isnewline__curr"
# get the current history number
prompt_command__isnewline__curr="$(history 1 | grep -oP '^\ +\K[0-9]+')"
[ "$prompt_command__isnewline__curr" = "$prompt_command__isnewline__last" ] && \
echo "User hit return"
}
Ora imposta la $PROMPT_COMMAND
variabile:
PROMPT_COMMAND="isnewline"
Vedi l'output:
user@host:~$ true
user@host:~$ <return>
User hit return
user@host:~$ <space><return>
user@host:~$
last
viene conservata da un richiamo isnewline
al successivo (scegli solo un nome meno generico come prompt_command__isnewline__last
per evitare scontri).
HISTCONTROL="" function last_was_blank { local last_command="$(history 1)" if [[ "$last_was_blank_PREVIOUS_LINE" = "$last_command" ]] ; then echo "true" else echo "false" fi export last_was_blank_PREVIOUS_LINE="$last_command" } PROMPT_COMMAND=last_was_blank
Non conosco un modo per farlo, di per sé . Ma puoi ottenere lo stesso effetto usando
trap debug some_command_or_function
Questo farà sì some_command_or_function
che venga chiamato ogni volta che si esegue un comando. La cosa difficile è che non verrà chiamato se colpisci semplicemente Enter- a meno che tu non abbia definito un PROMPT_COMMAND, nel qual caso colpire Enterinvoca il PROMPT_COMMAND, che, a sua volta, attiva la trappola.
Forse il modo più semplice per ottenere il risultato desiderato è definire una funzione trap di debug invece di utilizzare un PROMPT_COMMAND. Ma non posso dirlo, perché non so quale risultato desideri. Se vuoi che accada qualcosa quando hai appena colpito Entere qualcosa di diverso / aggiuntivo accade quando digiti un comando, allora (AFAIK) devi usare una trap di debug e un PROMPT_COMMAND. Vedi questa risposta e questa per un modo per far funzionare bene i due meccanismi insieme.
(Questo sarebbe stato un commento alla risposta accettata se mi fosse stato permesso di aggiungere commenti ...) @schlimmen, potresti impostare HISTTIMEFORMAT
qualcosa di simile HISTTIMEFORMAT='%F %T '
e quindi salvare e confrontare history 1
. È perché con le cancellazioni almeno il timestamp dell'ultimo (possibilmente ripetuto) ultimo comando cambia ogni volta --- e con un'impostazione HISSTIMEFORMAT
appropriata, history 1
visualizzerà il timestamp (a differenza di fc
), e quindi differisce anche tra i comandi ripetuti.