Jake McCrary

Put the last command's run time in your Bash prompt

An updated version of this post can be found here

I’m fairly certain the following scenario has happened to every terminal user. You run a command and, while it is running, realize you should have prefixed it with time. You momentarily struggle with the thought of killing the command and rerunning it with time. You decide not to and the command finishes without you knowing how long it took. You debate running it again.

For the last year I’ve lived in a world without this problem. Upon completion, a command’s approximate run time is displayed in my prompt. It is awesome.

Overview

Most of the code below is from a post on Stack Overflow. It has been slightly modified to support having multiple commands in your $PROMPT_COMMAND variable. Below is a minimal snippet that could be included in your .bashrc.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function timer_start {
  timer=${timer:-$SECONDS}
}

function timer_stop {
  timer_show=$(($SECONDS - $timer))
  unset timer
}

trap 'timer_start' DEBUG

if [ "$PROMPT_COMMAND" == "" ]; then
  PROMPT_COMMAND="timer_stop"
else
  PROMPT_COMMAND="$PROMPT_COMMAND; timer_stop"
fi

PS1='[last: ${timer_show}s][\w]$ '

Modify your .bashrc to include the above and you’ll have a prompt that looks like the image below. It is a minimal prompt but it includes the time spent on the last command. This is great. No more wondering how long a command took.

Example of prompt

The details

timer_start is a function that sets timer to be its current value or, if timer is unset, sets it to the value of $SECONDS. $SECONDS is a special variable that contains the number of seconds since the shell was started. timer_start is invoked after every simple command as a result of trap 'timer_start' DEBUG.

timer_stop calculates the difference between $SECONDS and timer and stores it in timer_show. It also unsets timer. Next time timer_start is invoked timer will be set to the current value of $SECONDS. Because timer_stop is part of the $PROMPT_COMMAND it is executed prior to the prompt being printed.

It is the interaction between timer_start and timer_stop that captures the run time of commands. It is important that timer_stop is the last command in the $PROMPT_COMMAND. If there are other commands after it then those will be executed and their execution might cause timer_start to be called. This results in you timing the length of time between the prior and current prompts being printed.

My prompt

My prompt is a bit more complicated. It shows the last exit code, last run time, time of day, directory, and git information. The run time of the last command is one of the more useful parts of my prompt. I highly recommend you add it to yours.

My prompt

Errata

2015/5/04

Gary Fredericks noticed that the original code sample broke if you didn’t already have something set as your $PROMPT_COMMAND. I’ve updated the original snippet to reflect his changes.

Looking forward to the next article? Never miss a post by subscribing using e-mail or RSS. The e-mail newsletter goes out periodically (at most once a month) and includes reviews of books I've been reading and links to stuff I've found interesting.

Comments