Discussion:
Command not found with builtins and variables
b***@feusi.co
2018-10-10 11:42:50 UTC
Permalink
Hi,
I'm not exactly sure if the following is actually a bug or whether bash
is actually supposed to behave like this. However, I couldn't find any
documentation concerning it so I decided to ask.

The thing I noticed is that when setting a variable and then running the
command "time", bash reports "command not found". For example, the
command:

TEST=1 time ls

Results in "bash: time: command not found"
At first, I believed that this was inherent to the bash builtins but I discovered
that

TEST=1 cd

Works without any problems, so I am confused as to why bash behaves in
this manner. Is there any underlying reason to this behaviour or is this
a bug?

cheers,
project-repo
Greg Wooledge
2018-10-10 15:17:19 UTC
Permalink
Post by b***@feusi.co
TEST=1 time ls
time is not a builtin. It's a "keyword". It's a piece of the shell's
syntax. It has special magical rules that apply to nothing else.

If you want to set an environment variable in the temporary execution
environment of a command, and time how long that command takes, then
you write it like this:

time TEST=1 something that is not actually ls because ls does not use \$TEST
Post by b***@feusi.co
TEST=1 cd
Works without any problems,
Completely useless. cd does not use environment variables.

Stop OBFUSCATING your questions.

Post the ACTUAL QUESTIONS with the ACTUAL INTENT so we can answer them.
Chet Ramey
2018-10-10 15:23:26 UTC
Permalink
Post by b***@feusi.co
Hi,
I'm not exactly sure if the following is actually a bug or whether bash
is actually supposed to behave like this. However, I couldn't find any
documentation concerning it so I decided to ask.
The thing I noticed is that when setting a variable and then running the
command "time", bash reports "command not found". For example, the
TEST=1 time ls
Results in "bash: time: command not found"
You don't have a command named `time' in a directory in your $PATH.
Bash doesn't have a `time' builtin; it has a `time' reserved word.
Preceding `time' with a variable assignment removes its special meaning
and causes it to not be recognized as a reserved word.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://tiswww.cwru.edu/~chet/
Bob Proulx
2018-10-10 22:52:30 UTC
Permalink
Post by Chet Ramey
Post by b***@feusi.co
The thing I noticed is that when setting a variable and then running the
command "time", bash reports "command not found". For example, the
TEST=1 time ls
Results in "bash: time: command not found"
That would work if you installed the GNU time package.

https://www.gnu.org/software/time/

And it would produce the portable output format in both cases with the
time -p option, which is available both in the internal time and the
external GNU time command. Otherwise GNU time has its own unique and
different default output format.

$ TEST=1 time -p sleep 1
real 1.00
user 0.00
sys 0.00

But regardless of the external standalone time program... Order when
using the internal time here matters. Since 'time' is special it
should always be first. Put any variables to be set on the line
before the command by putting it before the command but after the
'time' word.

$ time TEST=1 sleep 1
real 0m1.003s
user 0m0.000s
sys 0m0.000s
Post by Chet Ramey
You don't have a command named `time' in a directory in your $PATH.
Well... *They* don't have a time program in PATH. But they could
have if they installed it. And many people do. :-)
Post by Chet Ramey
Bash doesn't have a `time' builtin; it has a `time' reserved word.
Preceding `time' with a variable assignment removes its special meaning
and causes it to not be recognized as a reserved word.
I might also mention that the bash 'time' needs this special status
because it times the entire pipeline.

$ time sleep 1 | sleep 2
real 0m2.004s
user 0m0.003s
sys 0m0.002s

Therefore conversely if someone is using the external time it might
give them an unexpected result. Since the external time will not know
anything about a pipeline. So this might catch people off guard too.

$ TEST=foo time -p sleep 1 | sleep 2
real 1.00
user 0.00
sys 0.00

When used it is best to always put 'time' first on the command line,
variables second, and commands after that. Order matters[1].

Bob

[1] OT: In English the order also matters and it is always
opinion, size, age, shape, color, origin, material, purpose, noun.
Using any other order and it sounds really odd! Reference
"The Elements Of Eloquence: How To Turn The Perfect English Phrase."
by Mark Forsyth.
http://www.npr.org/2016/09/08/493157931/bbc-editor-highlights-often-overlooked-english-language-rule
Chet Ramey
2018-10-11 14:43:18 UTC
Permalink
Post by Bob Proulx
Post by b***@feusi.co
The thing I noticed is that when setting a variable and then running the
command "time", bash reports "command not found". For example, the
TEST=1 time ls
Results in "bash: time: command not found"
That would work if you installed the GNU time package.
Maybe. Maybe not. It depends on $PATH. It's unlikely that his system
does not already have a `time' command, so if it's not found, it must
not be in $PATH.
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU ***@case.edu http://tiswww.cwru.edu/~chet/
Loading...