[nycbug-talk] Optional Variable Assignments and Builtins in ``Simple Commands''

Matthew Story matthewstory at gmail.com
Thu May 3 13:26:50 EDT 2012

Given a little bit of discussion last night surrounding the following

VAR=VAL; for i in 1 2 3; do echo "$VAR"; done
VAR=VAL for i in 1 2 3; do echo "$VAR"; done

I decided to take Jan's advice and "test all the things" in bash, dash and
FreeBSD sh:

bash $ VAR=VAL for i in 1 2 3; do echo "$VAR"; done
-bash: syntax error near unexpected token `do'
dash $ VAR=VAL for i in 1 2 3; do echo "$VAR"; done
/bin/sh: for: not found
freebsd sh$ VAR=VAL for i in 1 2 3; do echo "$VAR"; done
Syntax error: "do" unexpected

None of them seem to work, so I took a look at the POSIX 1.2008 Shell
Command Language Specification for Simple Commands (
which says that the ``command'' lookup following an optional variable
assignment is subject to the rules governing ``Command Search and
Execution'' (
 The rules governing this search (without a slash) starts with ``Special
Builtins'', then functions, then moves to a few utilities that will always
execute even if they are not in PATH, followed by a PATH search.  When we
look at the list of ``Special Builtins'', we will see that ``for'' is not
there (
 The reason for this is that ``for'' is a reserved word (
which just means that for is a part of the grammar of shell itself, and is
not a command.

So, assuming that we do have a special built-in, let's say eval ...

bash $ VAR=VAL eval echo \$VAR
dash $ VAR=VAL eval echo \$VAR
freebsd sh$ VAR=VAL eval echo \$VAR

All of our shells do support the optional variable assignment syntax for
simple commands, as required by the spec.  So now to the second question
from last night, does optional variable assignment effect the environment
of the shell itself, when combined with a special built-in, or do they only
effect the environment of the shell itself for the duration of the
execution of the special built-in ...

bash $ VAR=VAL eval echo \$VAR
bash $ echo $VAR

bash $
dash $ VAR=VAL eval echo \$VAR
dash $ echo $VAR
freebsd sh $ echo $VAR

So, the answer here is that it depends on the shell ... and that is largely
because the POSIX standard is mostly silent about this:

If no command name results, variable assignments shall affect the current
execution environment. Otherwise, the variable assignments shall be
exported for the execution environment of the command and shall not affect
the current execution environment (except for special built-ins).

I believe that either the behavior of bash here is incorrect, or that
either behavior is permissible.  But it should be assumed that when using a
special built-in with optional variable assignment on the command line,
that the variable value may persist in the current execution environment.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.nycbug.org/pipermail/talk/attachments/20120503/f8f21045/attachment.html>

More information about the talk mailing list