Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: time command with shell builtins



On 1/23/23, Dominik Vogt <dominik.vogt@xxxxxx> wrote:
> On Mon, Jan 23, 2023 at 07:31:12PM +0100, Mikael Magnusson wrote:
>> On 1/23/23, Dominik Vogt <dominik.vogt@xxxxxx> wrote:
>> > On Mon, Jan 23, 2023 at 02:42:05PM +0100, Roman Perepelitsa wrote:
>> >> On Mon, Jan 23, 2023 at 2:40 PM Dominik Vogt <dominik.vogt@xxxxxx>
>> >> wrote:
>> >> >
>> >> > Is it possible to get timing statistics of shell builtins too?
>> >> > Timing "echo" isn't very interesting, but timing loop constructs
>> >> > would be:
>> >> >
>> >> >   $ time while foo; do bar done
>> >>
>> >> This:
>> >>
>> >>     % time ( while foo; do bar; done )
>> >
>> > That wasn't really the question.  Of course I can time a loop by
>> > writing a different command, or by putting it in a pipe or file.
>> >
>> >   $ time echo foo | true
>> >
>> > I just want to get timing statistics of loops either explicitly by
>> > prepending "time" or implicitly with REPORTTIME.
>>
>> As Bart already mentioned, the answer to your question is "no", but
>> you can avoid some downsides of the subshell (eg, if your loop has
>> side effects that are relevant to the rest of the script etc), by
>> using SECONDS:
>> % () { typeset -F4 SECONDS=0; sleep 1; () { typeset -F3 SECONDS=0;
>> sleep 0.43; echo $SECONDS }; sleep 1; echo $SECONDS }
>> 0.431
>> 2.4329
>> (the downside here is obviously that it doesn't split out cpu/system
>> time for you, only elapsed time).
>
> Well, the worst downside for me is that REPORTTIME does not work.
> The use case is "oh, that command ran a long time, I'd really
> like to know how long it took".  I see no solution for that if
> re-running the command is no optiuon because it takes too long.
>
> At the moment I'm writing some automation scripts that run for
> hours and print their progress.  I might want to kill them after a
> few hours and see how many seconds they ran and compare it to the
> progress output.

What you can do at the moment is a) put the time in your prompt (and
reset the prompt on accept-line), b) save the current time in preexec
and compare it against the current time in precmd and print it out if
it exceeds some threshold(, c) or both).

a)
  zle -N accept-line _accept_line
  function _accept_line () {
    zle .reset-prompt
  }

b)
  zmodload zsh/datetime
  function precmd_showtime() {
    if ! (( ${+_zsh_time} )); then return 0; fi
    if (( $EPOCHSECONDS - $_zsh_time > 10 )); then
      printf "%i seconds elapsed\n" $(( EPOCHSECONDS - _zsh_time ))
    fi
    unset _zsh_time
  }

  function preexec_recordtime() {
    typeset -g _zsh_time
    _zsh_time=$EPOCHSECONDS
  }

-- 
Mikael Magnusson




Messages sorted by: Reverse Date, Date, Thread, Author