Archives

Categories

Timing Processes

One thing that happens periodically is that I start a process from an interactive shell, discover that it takes longer than expected, and then want to know how long it took. Basically it’s a retrospective need to have run “time whatever” that I discover after the process has been running for long enough that I don’t want to restart it. My current procedure in such situations is to run ps from another session to discover when it started and then type date to display when it ends.

A quick test with strace showed that bash uses the wait4() system call to determine when a process ends, but passes NULL as the last parameter. If it passed the pointer to a struct rusage then it would have the necessary data.

I think it would be a really good feature for a shell to allow you to type something like “echo $TIME_LAST_CMD” to see how long the last command took. For the common case where you aren’t interested in that data it would only involve an extra parameter to the wait4() system call, a small amount of memory allocated for it, and to store yet another environment variable in it’s list.

A quick Google search didn’t show any way of filing wishlist bugs against Bash and I don’t think that this is a real bug as such so I haven’t filed a bug report. If anyone reads my blog and has some contact with the Bash people then please pass this idea along if you think it’s worthy of being included.

6 comments to Timing Processes

  • Anonymous

    Seconded; I often find myself wanting this as well.

    Why not file a wishlist bug in Debian, so it doesn’t get lost?

  • Not that you’re looking to switch shells, but one of the things I love about tcsh is that I can set the variable $time to a number (I use 3 myself), and any command I run that takes more than that many CPU seconds will print the output of the ‘time’ command after it completes. It would be nicer if the threshold was measured in wall clock seconds, but I’ll take what I can get.

  • Leandro Penz

    I don’t know about bash, but in zsh it is quite simple using the precmd and preexec hooks:

    precmd() {
    [[ -t 1 ]] || return
    [[ -n “$PROC_NAME” ]] && [[ $(( $SECONDS – $PROC_START )) -gt 5 ]] && echo $PROC_NAME took $(( $SECONDS – $PROC_START )) seconds
    PROC_NAME=
    }

    preexec() {
    [[ -t 1 ]] || return
    PROC_START=$SECONDS
    PROC_NAME=$2
    }

  • milosh

    The configuration of zsh provided by grml does that: whenever a command takes more than 5 seconds. It relies on zsh’s extended_history (which saves the timestamp of the beginning of each command).

  • Corsac

    The zsh variable you want is: REPORTTIME=2 (all jobs running for more than 2 secs are reported)

  • I found a way to *almost* accomplish this with the PROMPT_COMMAND in bash. I set it to a function that includes this snippet:

    LASTCMDTIME=`history 1 | awk ‘BEGIN {FS=” “} {print $2,$3,$4}’
    echo “Prev cmd: $LASTCMDTIME”

    Since I also have the current time in the prompt, I can see how long a command was running for.