Bash’s builtin time accepts %E – what’s going on

bashtime

The bash man page lists three and only three format codes recognized by the shell's builtin version of time: %R for the real time, %U for the time spent in userspace, and %S for time spent in system calls. So the following behavior is confusing to say the least:

$ type time
time is a shell keyword
$ TIMEFORMAT="%E %P"
$ time sleep 1
1.002 0.00

Clearly something is being left out of the man page. The builtin time is recognizing %E and %P. However I checked all other uppercase and lowercase letters and none of them are recognized, except l as a modifier:

$ TIMEFORMAT="%lE %lS %lU %lR"
$ time sleep 1
0m1.001s 0m0.000s 0m0.000s 0m1.001s

I'm curious to understand what's going on here – is this really just an omission in the man page, or is there something weird about my bash? Ideally, can anyone point me to some documentation that explains this? I'm using bash 4.2.48(1) on Gentoo amd64 stable, if it matters.

Best Answer

From the section of execute_cmd.c of bash-4.2+dfsg that deals with TIMEFORMAT:

if (*s == 'R' || *s == 'E')
  len = mkfmt (ts, prec, lng, rs, rsf);
else if (*s == 'U')
  len = mkfmt (ts, prec, lng, us, usf);
else if (*s == 'S')
  len = mkfmt (ts, prec, lng, ss, ssf);
else
  {
    internal_error (_("TIMEFORMAT: `%c': invalid format character"), *s);
    free (str);
    return;
  }

So, from the above, it appears that %E means the same as %R: elapsed (real) time.

I have seen something similar in GNU sed. The -r option is documented as enabling sed's extended regular expressions. An undocumented feature is that -E does the same thing. In this case, the purpose is clear: this provides compatibility with the flag that BSD sed uses for extended regex. One possible reason for keeping it undocumented would be that it allows GNU the option to use -E for something else in the future. The reasons for allowing %E in TIMEFORMAT but keeping it undocumented might be similar.