2016-02-25 03:03:41 -0800, Linda Walsh: > Stephane Chazelas wrote: > >$ time bash -c 'while ((SECONDS < 1)); do :; done' > >bash -c 'while ((SECONDS < 1)); do :; done' 0.39s user 0.00s system 99% cpu > >0.387 total > > > >That can take in between 0 and 1 seconds. Or in other words, > >$SECONDS becomes 1 in between 0 and 1 second after the shell was > >started. > The format you are using to display output of 'time' doesn't show > real time -- only CPU seconds.
It does. The last number (0.387 total) is the elapsed time in the output of zsh (my interactive shell)'s "time" keyword. CPU times are 0.39s user and 0.00s system totalling to 0.39s Because it's a busy loop, CPU time is close to 100% (99%) so elapsed and CPU time are roughly the same. > Try: > > TIMEFORMAT='%2Rsec %2Uusr %2Ssys (%P%% cpu)' That would be for bash. In anycase, bash does already include the elapsed time in its default time output like zsh. But the problem here is not about the time keyword, but about the $SECONDS variable. [...] > With linux, one can read /proc/uptime to 100th's of a sec, or > use date to get more digits. A middle of the road I used for > trace timing was something like: > > function __age { declare ns=$(date +"%N"); declare -i > ms=${ns##+(0)}/1000000; > printf "%4d.%03d\n" $SECONDS $ms > } [...] I'm not sure how that gives you the time since startup. Currently, if bash is started at 00:00:00.7 After 0.4 seconds (at 00:00:01.1), $SECONDS will be 1 (the "bug" I'm raising here). "ms" will be 100, so you'll print 1.100 instead of 0.600. And with my suggested fix, you'd print 0.100. [...] > As you can see, I wanted the times > relative to the start of a given script, thus used SECONDS for that. Note that all of zsh, ksh93 and mksh have builtin support to get elapsed time information with subsecond granularity. zsh has: - $SECONDS: time since shell start. floating point after typeset -F SECONDS - $EPOCHSECONDS (unix time) (in zsh/datetime module) - $EPOCHREALTIME: same as floating point - zselect builtin to sleep with 1/100s granularity (in zsh/zselect module) - the "time" keyword, without a command prints CPU and real time for the shell and waited-for ancestors (and other getrusage statistics you can add with TIMEFMT) ksh93 has: - $SECONDS: time since shell start. floating point after typeset -F SECONDS - EPOCHREALTIME=$(printf '%(%s.%N)T' now) for unix time as a float (note that you need a locale where the decimal separator is a period to be able to use that in ksh arithmetic expressions, or you need to replace that "." with a "," above). - builtin sleep with sub-second granularity mksh has: - $EPOCHREALTIME: unix time as floating point (note however that mksh doesn't support floating point arithmetic). - builtin "sleep" command with sub-second granularity. Similar features would be welcome in bash. bash has "times" that gives you CPU time with sub-second granularity. It's got a "printf %T" a la ksh93, but no %N, its $SECOND is only integer (and currently has that issue discussed here). It does supports a $TMOUT with sub-second granularity though. You can use that to sleep for sub-second durations if you find a blocking file to read from. On Linux, that could be: TMOUT=0.4 read < /dev/fd/1 | : but that still means forking processes. -- Stephane