8

@mpy 's comment was correct. So I'm rephrasing my question. I really like REPORTTIME feature in zsh, but it only reports time when user+system time is greater than $REPORTTIME according to zsh doc. Is there a way to make zsh report time when wall time is greater than some number, but not report time when wall time is below that number?

Original Question: I really like REPORTTIME feature in zsh, but according to the zsh doc, it will only output when command result is nonzero. But there are some cases when some command takes a while and fails, and I want to know how long it took. Does anyone know a way to print out time for the command even if the result failed?

2
  • 2
    IMHO the doc ("REPORTTIME If nonnegative,...") refers to $REPORTTIME itself, not the return status of the command. Note, that the user+system time must be greater than $REPORTTIME, not the wall time. So sleep 2 doesn't report a statistics even with REPORTTIME=1
    – mpy
    Oct 10, 2013 at 11:24
  • Thanks for the comments. I see... My command took over 10 mins and failed, so I'll check with time command to see what the user+system time was in the case that didn't work.
    – ktsujister
    Oct 11, 2013 at 6:47

1 Answer 1

11
+100

The functionallity of REPORTTIME appears to be hard coded to compare usertime+systime. The relevant zsh source code for the REPORTTIME functionality:

#ifdef HAVE_GETRUSAGE
    reporttime -= j->procs->ti.ru_utime.tv_sec + j->procs->ti.ru_stime.tv_sec;
    if (j->procs->ti.ru_utime.tv_usec +
    j->procs->ti.ru_stime.tv_usec >= 1000000)
    reporttime--;
    return reporttime <= 0;
#else
    {
    clktck = get_clktck();
    return ((j->procs->ti.ut + j->procs->ti.st) / clktck >= reporttime);
    }
#endif

As an alternative solution, you can modify your zshrc to obtain functionallity simalar to having REPORTTIME use total running time.

REPORTTIME_TOTAL=5

# Displays the execution time of the last command if set threshold was exceeded
cmd_execution_time() {
  local stop=$((`date "+%s + %N / 1_000_000_000.0"`))
  let local "elapsed = ${stop} - ${cmd_start_time}"
  (( $elapsed > $REPORTTIME_TOTAL )) && print -P "%F{yellow}${elapsed}s%f"
}

# Get the start time of the command
preexec() {
  cmd_start_time=$((`date "+%s + %N / 1.0e9"`))
}

# Output total execution
precmd() {
  if (($+cmd_start_time)); then
    cmd_execution_time
  fi
}

Unfortunately, this command only gives total running time. It does not break down execution time into user and system time.

1
  • Wonderful! Seems to work great and doesn't require installing a plugin system. One addition: insert unset cmd_start_time at the end of precmd(), so that pressing Enter with an empty command doesn't print an (incorrect) time.
    – Cykelero
    Jun 27, 2023 at 16:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .