En bash, desde PROMPT_COMMAND, ¿hay alguna forma de saber si el usuario simplemente presionó 'regresar' y no ingresó un comando?
12
Compruebe si el número de historial se incrementó. Un aviso cancelado o un aviso donde el usuario acaba de presionar Enterno incrementará el número del historial.
El número de historial está disponible en la variable HISTCMD
, pero no está disponible en PROMPT_COMMAND
(porque lo que desea allí es, de hecho, el número de historial del comando anterior; el comando que se ejecuta PROMPT_COMMAND
solo no tiene número de historial). Puede obtener el número de la salida de 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'
Tenga en cuenta que si ha activado el aplastamiento de duplicados en el historial ( HISTCONTROL=ignoredups
o HISTCONTROL=erasedups
), esto informará erróneamente un comando vacío después de ejecutar dos comandos idénticos sucesivamente.
${HISTCMD_previous%%$'[\t ]'*}
faltaba el bit$'…'
y terminó truncado después de`,
t` o espacio en lugar de después de tabulación o espacio, pero bash imprime una ficha.Hay una solución alternativa, pero tiene algunos requisitos:
Debe configurar
$HISTCONTROL
para guardar TODOS los comandos, también duplicados y espacios. Entonces establece:Ahora defina una función para llamar como
$PROMPT_COMMAND
:Ahora, establezca la
$PROMPT_COMMAND
variable:Ver la salida:
fuente
last
se conserva de una invocaciónisnewline
a la siguiente (solo elija un nombre menos genéricoprompt_command__isnewline__last
para evitar conflictos).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
No sé de una manera de hacer eso, per se . Pero puedes obtener el mismo efecto usando
Esto hará
some_command_or_function
que se invoque cada vez que ejecute un comando. Lo complicado es que no se Enterinvocará si solo golpeas , a menos que tengas un PROMPT_COMMAND definido, en cuyo caso golpear Enterinvoca PROMPT_COMMAND, que, a su vez, activa la trampa.Quizás la forma más sencilla de lograr el resultado que desea es definir una función de captura de depuración en lugar de utilizar un PROMPT_COMMAND. Pero no puedo decirlo, porque no sé qué resultado quieres. Si desea que algo suceda cuando presiona Enter, y que suceda algo diferente / adicional cuando escribe un comando, (AFAIK) debe usar una trampa de depuración y un PROMPT_COMMAND. Vea esta respuesta y esta para una forma de hacer que los dos mecanismos jueguen bien juntos.
fuente
(Esto habría sido un comentario a la respuesta aceptada si me hubieran permitido agregar comentarios ...) @schlimmen, puede configurar
HISTTIMEFORMAT
algo asíHISTTIMEFORMAT='%F %T '
y luego guardar y compararhistory 1
. Es porque con borrados al menos la marca de tiempo del último comando (posiblemente repetido) cambia cada vez --- y conHISSTIMEFORMAT
el ajuste apropiado,history 1
mostrará la marca de tiempo (a diferenciafc
) y, por lo tanto, diferirá incluso entre los comandos repetidos.fuente