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

Re: time command with shell builtins



On Tue, Jan 24, 2023 at 11:48:39AM +0100, Dominik Vogt wrote:
> On Tue, Jan 24, 2023 at 10:32:35AM +0100, Mikael Magnusson wrote:
> > 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).
>
> Good idea.  This is what I use now:
>
> -- snip --
> autoload -Uz add-zsh-hook
> zmodload zsh/datetime
>
> function preexec_recordtime() {
> 	typeset -g _zsh_time
> 	_zsh_time="$EPOCHSECONDS"
> }
> add-zsh-hook preexec preexec_recordtime
>
> function __prompt_get_displaytime () {
> 	if ! (( ${+_zsh_time} )); then return 0; fi
> 	if ! (( ${+REPORTTIME} )); then return 0; fi
> 	if (( $EPOCHSECONDS - $_zsh_time > $REPORTTIME )); then
> 		printf " $[EPOCHSECONDS - _zsh_time]s"
> 	fi
> 	unset _zsh_time
> }
>
> PS1="<...>$(__prompt_get_displaytime)<...>"
> -- snip --

Hm, any idea how to suppress reporting the run time of interactive
commands like vi, emacs, mutt?  Not very important, but it's a bit
confusing.  As far as I understand there's no reliable access to
which command is being executed in preexec.  I could replace such
commands by functions that erase _zsh_time when they start...

Ciao

Dominik ^_^  ^_^

--

Dominik Vogt




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