Eric Blake wrote: > Doug McIlroy wrote: > | So there's a bug in the manual, which does not breathe a word about > | time being executed by the shell. And the shell covers its tracks, too: > > Like I said, there's a difference between a builtin (for example, > 'builtin' or 'exec') and a reserved word (for example, 'time' or 'if').
In the bash manual I am reading I see: RESERVED WORDS Reserved words are words that have a special meaning to the shell. The following words are recognized as reserved when unquoted and either the first word of a simple command (see SHELL GRAMMAR below) or the third word of a case or for command: ! case do done elif else esac fi for function if in select then until while { } time [[ ]] ... If the time reserved word precedes a pipeline, the elapsed as well as user and system time consumed by its execution are reported when the pipeline terminates. The -p option changes the output format to that specified by POSIX. The TIMEFORMAT variable may be set to a format string that specifies how the timing information should be displayed; see the description of TIMEFORMAT under Shell Variables below. ... Pipelines A pipeline is a sequence of one or more commands separated by the char‐ acter |. The format for a pipeline is: [time [-p]] [ ! ] command [ | command2 ... ] And a command is defined as: Simple Commands A simple command is a sequence of optional variable assignments fol‐ lowed by blank-separated words and redirections, and terminated by a control operator. The first word specifies the command to be executed, and is passed as argument zero. The remaining words are passed as arguments to the invoked command. > > % export X=x; time --version; unset X > > -bash: --version: command not found Here time is the shell's version because it occurs at the start of the pipeline, which in bash does not implement a --version option to it. > > % unset X; X=x time --version > > GNU time 1.7 Here the environment variable assignment matches a 'command' and therefore 'time' is an external command. Further, because for an individual command do not affect the current environment this implies to me that the command must have its own environment. The manual says: If no command name results, the variable assignments affect the current shell environment. Otherwise, the variables are added to the environ‐ ment of the executed command and do not affect the current shell envi‐ ronment. If any of the assignments attempts to assign a value to a readonly variable, an error occurs, and the command exits with a non- zero status. This implies to me that a variable assignment forces subsequent commands to be external commands because the current environment is not affected. In your case above the external /usr/bin/time program is forced by the variable assignment requiring the environment variable set for it. > | Were I still the keeper of Unix manuals, my fix to the manual > | would be to list this wart under BUGS. > > 'man bash' correctly lists time under the section RESERVED WORDS. Also, > 'help time' gives evidence that it is special to bash (as 'help' is the > bash builtin that reports about both reserved words and builtins). I will leave that decision up to the maintainer. I could go either way. However there are so many edge cases that might trip up someone that if every one of them were documented in the bugs section then that section would be far longer than the rest of the manual. In the end many of these cases simply become judgement calls. Bob