Including command duration in your bash prompt

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.

Leave a Reply