5

Most of the things I run in the terminal take a long time to compute and I would like to have bash output a time report at the end of every command entered into the terminal. Is there something I can put into my bashrc to do this?

Example:

$ find / -ls
<find / -ls return info>
start time = 10:21:54 | end time = 10:31:34 | time lapsed = 00:10:20
$

or

$ make all
<make all return info>
start time = 10:21:54 | end time = 10:31:34 | time lapsed = 00:10:20

It would be nice to be able to add a list of exceptions for commands like cd, but it wouldn't really bother me.

  • 1
    time will give you most of what you need but I'm not sure how to add it automatically. – terdon Nov 19 '13 at 17:41
  • That was my first thought as well. It's nice to be in good company! – Rob Nov 19 '13 at 17:48
  • I think that for the "end time" PROMPT_COMMAND can be used... – Braiam Nov 19 '13 at 17:54
  • Related: http://unix.stackexchange.com/a/44723/22222, http://stackoverflow.com/a/1177511/1081936. Combining those with @Braiam's PROMPT_COMMAND suggestion should be possible but I don't have time to play with it now. – terdon Nov 19 '13 at 18:06
  • you could edit your PS1 to display the $(date), and also use PROMPT_COMMAND to display another $(date) once the command finished. The problem though is that your prompt will only show the time the prompt appeared, not the time when you started the command. However, you just have to remember to press "Enter" one time before typing the important(/long) commands, to get a fresh starting time ... – Olivier Dulac Nov 19 '13 at 18:07
  • @OlivierDulac Or instead of pressing "Enter" before each long command, one can just trap 'date' DEBUG. – Joseph R. Nov 19 '13 at 18:14
  • Also relevant (perhaps a duplicate?): http://unix.stackexchange.com/q/12059/ – terdon Nov 19 '13 at 20:55

2 Answers2

3

I tried the following in my .bashrc:

echo -ne "$PS1"
while IFS= read -er line;do
    eval "time $line"
    echo -ne "$PS1"
done

This roughly does what you want with several caveats:

  • Your prompt is practically ruined (the shell usually interprets sequences like \W and so on in your prompt before echoing it).
  • You lose command line editing capabilities (e.g. you can't use CTRL + L for clear).
  • Probably several others.

I guess a good compromise would be to enable this selectively via a shell function:

timed_commands() {
    [ "$1" = off ] && exec bash
    PS1='$ '  # Put something simple here
    while IFS= read -erp "$PS1" line;do
        eval "time $line"
    done
}

Turn it on with timed_commands and turn it off with timed_commands off

Thanks to @jthill's comment for the -e switch to read.

Joseph R.
  • 39,549
1

now this is hackish as all hell but it may work ...

set the terminal id string (the string returned by inquire) to "time ". notice the trailing space. next set your prompt to end with an inquire. now every time your prompt is displayed, the terminal automatically types time and a space for you, at which point you type your command. this won't work with all terminals because many have disabled this functionality to prevent this from happening.

To get this to work with xterm add the following line to your .Xresources and reload it with xrdb

xterm*answerbackString: time ^[0D^[0A
URxvt*answerbackString: time ^[0D^[0A
xterm_color*answerbackString: time ^[0D^[0A

where ^[ is an escape (because xterm doesn't like space at the end of the answerbackString I wiggle the cursor.

next add the ENQ to the end of your prompt string (bash specific example):

PS1="${PS1}\[\005\]"

start a new shell in a fresh xterm and cross your fingers it should work. the \005 is a ENQ the [ and ] tells bash that the \005 doesn't move the cursor.

hildred
  • 5,829
  • 3
  • 31
  • 43
  • 1
    Hi and welcome to U&L. While this answer may well be useful, it is hard to understand unless one is an expert. Could you add some more details? What's "the string returned by inquire"? How do you "set your prompt to end with an inquire"? – terdon Nov 19 '13 at 20:49