En bash, ¿puedo hacer arreglos para que se ejecute una función justo antes de ejecutar un comando?
Existe $PROMPT_COMMAND
, que se ejecuta antes de mostrar una solicitud, es decir, justo después de ejecutar un comando.
Bash $PROMPT_COMMAND
es análogo a la precmd
función de zsh ; así que lo que estoy buscando es un bash equivalente a zsh's preexec
.
Aplicaciones de ejemplo: establezca el título de su terminal para el comando que se ejecuta; agregar automáticamente time
antes de cada comando.
command-line
bash
hook
Gilles
fuente
fuente
PS0
variable que actúa comoPS1
pero se usa después de leer el comando pero antes de ejecutarlo. Consulte gnu.org/software/bash/manual/bashref.html#Bash-VariablesRespuestas:
No de forma nativa, pero se puede hackear usando la
DEBUG
trampa. Este código se configurapreexec
yprecmd
funciona de manera similar a zsh. La línea de comando se pasa como un argumento único apreexec
.Aquí hay una versión simplificada del código para configurar una
precmd
función que se ejecuta antes de ejecutar cada comando.Este truco se debe a Glyph Lefkowitz ; Gracias a bcat por localizar al autor original.
Editar. Puede encontrar una versión actualizada del truco de Glyph aquí: https://github.com/rcaloras/bash-preexec
fuente
"$BASH_COMMAND" = "$PROMPT_COMMAND"
comparación no funciona para mí i.imgur.com/blneCdQ.pngtime for i in {1..10}; do true; done
toma 0.040 segundos normalmente y 1.400 a 1.600 segundos después de activar la trampa DEBUG. Hace que el comando trap se ejecute dos veces por bucle, y en Cygwin la bifurcación requerida para ejecutar sed es prohibitivamente lenta, aproximadamente 0.030 segundos para bifurcar solo (diferencia de velocidad entreecho
incorporado y/bin/echo
). Algo a tener en cuenta, tal vez.PROMPT_COMMAND
variable (por ejemplo delimitado por;
), puede que tenga que utilizar la coincidencia de patrones en la segunda línea de lapreexec_invoke_exec
función, al igual que este:[[ "$PROMPT_COMMAND" =~ "$BASH_COMMAND" ]]
. Esto se debe a queBASH_COMMAND
representa cada uno de los comandos por separado.Puede usar el
trap
comando (desdehelp trap
):Por ejemplo, para cambiar el título del terminal de forma dinámica, puede usar:
De esta fuente.
fuente
help trap
dice "Si un SIGNAL_SPEC es DEBUG, ARG se ejecuta después de cada comando simple" [énfasis mío].trap '[ -n "$COMP_LINE" ] && [ "$BASH_COMMAND" != "$PROMPT_COMMAND" ] && date "+%X";echo -e "\e]0;$BASH_COMMAND\007"' DEBUG
. Esto coloca el comando en el título y también imprime la hora actual justo antes de cada comando, pero no lo hace cuando se ejecuta$PROMPT_COMMAND
.[ -z "$COMP_LINE" ]
.No se ejecuta una función de shell, pero contribuí con una
$PS0
cadena de solicitud que se muestra antes de ejecutar cada comando. Detalles aquí: http://stromberg.dnsalias.org/~strombrg/PS0-prompt/$PS0
se incluye enbash
4.4, aunque la mayoría de los Linux tardarán un tiempo en incluir 4.4; sin embargo, puede compilar 4.4 usted mismo; en ese caso, probablemente debería ponerlo bajo/usr/local
, añadirlo a/etc/shells
ychsh
a ella. Luego, cierre la sesión y vuelva a iniciarla, quizás como pruebassh
para usted @ localhost osu
para usted primero.fuente
Recientemente tuve que resolver este problema exacto para un proyecto paralelo mío. Hice una solución bastante robusta y resistente que emula la funcionalidad preexec y precmd de zsh para bash.
https://github.com/rcaloras/bash-preexec
Originalmente se basó en la solución de Glyph Lefkowitz, pero la he mejorado y actualizado. Feliz de ayudar o agregar una función si es necesario.
fuente
Gracias por las pistas! Terminé usando esto:
¡Disfrutar!
fuente
Escribí un método para registrar todos los comandos / bash 'bash' en un archivo de texto o un servidor 'syslog' sin usar un parche o una herramienta ejecutable especial.
Es muy fácil de implementar, ya que es un simple shellscript que debe llamarse una vez en la inicialización de 'bash'.
Mira el método aquí .
fuente