Does bash have a hook that is run before executing a command?
Not natively, but it can be hacked up using the DEBUG
trap. This code sets up preexec
and precmd
functions similar to zsh. The command line is passed as a single argument to preexec
.
Here is a simplified version of the code to set up a precmd
function that is executed before running each command.
preexec () { :; }
preexec_invoke_exec () {
[ -n "$COMP_LINE" ] && return # do nothing if completing
[ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
local this_command=`HISTTIMEFORMAT= history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//"`;
preexec "$this_command"
}
trap 'preexec_invoke_exec' DEBUG
This trick is due to Glyph Lefkowitz; thanks to bcat for locating the original author.
Edit. An updated version of Glyph's hack can be found here: https://github.com/rcaloras/bash-preexec
You can use the trap
command (from help trap
):
If a SIGNAL_SPEC is DEBUG, ARG is executed before every simple command.
For example, to change the terminal title dynamically you may use:
trap 'echo -e "\e]0;$BASH_COMMAND\007"' DEBUG
From this source.
It's not a shell function that gets executed, but I contributed a $PS0
prompt string that is displayed before each command is run. Details here: http://stromberg.dnsalias.org/~strombrg/PS0-prompt/
$PS0
is included in bash
4.4, though it'll take a while for most Linuxes to include 4.4 - you can build 4.4 yourself if you want though; in that case, you probably should put it under /usr/local
, add it to /etc/shells
and chsh
to it. Then log out and back in, perhaps ssh
ing to yourself@localhost or su
ing to yourself first as a test.