For a long time I’ve had a dream: including the length of time it took for each command to run in my bash prompt.
Over the years I’ve looked into it a couple of times and seen partial “solutions” that were never quite what I wanted. The core of the problem being that there didn’t seem to be a way to get bash to run code before running each command, so there was no way for me to know when the command started – it seemed the best I could do was “how much time has elapsed since the previous command finished”, which is pretty useless info, because that measurement includes the (unknown) time it took me to type the next command.
The other day, I finally cracked it. The trick is to trap bash’s DEBUG signal:
# Include the duration of the previous command in bash prompt # By Dale Magee # Put (something like) this in your ~/.bashrc: # vars for command timing / info CMD_STARTED="" LAST_CMD="" time_me() { # this function runs before *each line* of your bash script. # we need to set the "command started" time at the beginning of the script # so we only set it once, if it's unset, and then we unset it after the # command has completed (in our promptcommand) if [ -z "$CMD_STARTED" ]; then CMD_STARTED=$(date +%s%N) # %N - nanoseconds LAST_CMD="$BASH_COMMAND" fi } trap 'time_me' DEBUG myprompt() { RESULT=$? if [ -n "$CMD_STARTED" ]; then # figure out duration of command TOOK=$(($(date +%s%N) - CMD_STARTED)) # get duration in nanoseconds TOOK=$(echo "scale=3; $TOOK / 1000000000" | bc -q 2>/dev/null) # nanoseconds -> fractional seconds else # unknown duration TOOK="??" fi # empty CMD_STARTED so that it will be set next time time_me is called CMD_STARTED="" # your custom prompt stuff goes here # you can also use $LAST_CMD here too if you like # (but note it's the full command line - might be long) PS1="\u@\h:\w $WHITE(${TOOK}s)$NO_COLOUR $ " } PROMPT_COMMAND=myprompt
Notes:
1. This only works if you use tab for indentation.