6

Is it possible to have your bash history save the total execution time of every command you run?

i.e. as if every command were prefaced with 'time' and the result was stored in the history along with the command?

clarification: I already know that you can add a timestamp of when the command was started - but I would like to know the total execution time, not just when it was started.

1

3 Answers 3

3
+50

You can try by modifying the PROMPT_COMMAND environment variable to automatically log the execution time for each command. This approach integrates the logging mechanism directly into the shell environment, making it seamless.

  1. Edit your profile:
nano ~/.bashrc
  1. Add the following functions to the end of the profile:
preexec() {
    history -a
    start=$(date +%s)
}

precmd() {
    end=$(date +%s)
    duration=$(( end - start ))
    command=$(history 1 | sed 's/^ *[0-9]* *//')
    history -s "${command} # Execution time: ${duration}s"
}

trap 'preexec' DEBUG
PROMPT_COMMAND='precmd'
  1. Source to apply:
source ~/.bashrc

With this each command will automatically log execution time to history. The preexec function captures the start time of the command, and the precmd function calculates duration and logs it to history.

Something close to this might work

1
  • 1
    Some issues, but promising direction! This duplicates entries, duration is always 0s, should use the comment character (#), and formatting's tricky due to unique history formats Commented Jan 14 at 5:45
1

By defining HISTTIMEFORMAT in your startup scripts, you will have a timestamp added to every line of your bash history file. The value of this variable is the way (*) timestamps must be printed on the screen. Here is mine :

HISTTIMEFORMAT='%F-%T '

(*) See man 3 strftime (if you don't have it, man date should do the trick)

1
  • 3
    yes, that will tell you what time you ran the command - but not the total execution time of it. Commented Dec 5, 2016 at 15:26
1

Child process usage is set somewhere within the wait3 or wait4 system calls via a struct rusage pointer (wait4(2)). Under the bash sources, we find:

$ egrep -r 'wait[34][[:blank:]]*\(' .
./jobs.c:   wait3 ((union wait *)statusp, options, (struct rusage *)0)
./jobs.c:   wait3 (statusp, options, (struct rusage *)0)
./jobs.c:   wait3 (statusp, options, (int *)0)
$

The blank (struct rusage *)0 indicates that the resource usage will not be returned to bash. A struct rusage search does turn up time_command function in execute_cmd.c, and this does appear to collect usage information via getrusage(2). However, this is for the TIMEFORMAT of the time builtin, and does not appear to intersect with the history code. Without patching bash, I guess you'd have to do some sort of kluge involving running everything under time and then capturing the standard error the time information appears on to some file?

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.