5

Reading env POSIX documentation:

Some have suggested that env is redundant since the same effect is achieved by:

name=value ... utility [ argument ... ]

The example is equivalent to env when an environment variable is being added to the environment of the command, but not when the environment is being set to the given value. The env utility also writes out the current environment if invoked without arguments. There is sufficient functionality beyond what the example provides to justify inclusion of env.

AFAICT, the above statement meaning var=value command will be the same as env var="value" command, and not when using as env -i var="value" command.

Now, at least with env implementation on GNU system, FreeBSD and Solaris 11, I realize that they're not equivalent, because env allow any characters, except = and \0 in var name:

$ env 'BASH_FUNC_foo%%=() { echo foo; }' bash -c foo

print foo, while you can't use BASH_FUNC_foo%%='() { echo foo; }' in any shells, because BASH_FUNC_foo%% clearly not a valid variable name.

In POSIX shells, except bash, this left a variable named BASH_FUNC_foo%% in environment variables, which the shell can not access it.

So, what is the purpose of allowing arbitrary name in form env var=value and was it allowed by POSIX?

6
  • 2
    I don't see any use for it and IMO almost every use of env is a mistake.....especially including the python crowd's promotion of using env on the #! line of a script file. See unix.stackexchange.com/questions/29608/… for interesting debate on the topic.
    – cas
    Commented Oct 2, 2015 at 5:19
  • @cas: One usage of it was shown in my question, it allow you to define function in environment variable in bash.
    – cuonglm
    Commented Oct 2, 2015 at 6:28
  • virtualenv seems like a great re-implementation of DLL Hell. Programmers probably love it. Sysadmins generally hate it.
    – cas
    Commented Oct 2, 2015 at 7:12
  • 2
    The shells can't access these variables, true. But why should that prevent a program written in C or Python from accessing them?
    – muru
    Commented Oct 2, 2015 at 7:35
  • 1
    @muru, yes, and other non-POSIX shells. Like rc that allows anything in a variable name (and where all variables are exported). Commented Oct 5, 2015 at 19:35

2 Answers 2

5
+100

So, what is the purpose of allowing arbitrary name in form env var=value and was it allowed by POSIX?

Quoting from POSIX: Environment Variables:

Environment variable names used by the utilities in the Shell and Utilities volume of POSIX.1-2008 consist solely of uppercase letters, digits, and the ( '_' ) from the characters defined in Portable Character Set and do not begin with a digit. Other characters may be permitted by an implementation; applications shall tolerate the presence of such names.

Note: Other applications may have difficulty dealing with environment variable names that start with a digit. For this reason, use of such names is not recommended anywhere.

So implementations of env may permit arbitrary environment variable names - and most, if not all, implementations do so, accepting every non-NUL character to the left of an '=' - and implementations of other utilities (such as the shell) may or may not permit arbitrary names.

The statement that name=value ... utility is equivalent to env var="value" utility will only be true if the implementation of env and the shell both permit name to be an environment variable.

There's an interesting Austin Group thread about this issue here: Invalid shell assignments in environment. One point mentioned is that shells generally only allow environment variables whose names can be represented as shell variables. Several participants in that thread participate in unix.stackexchange.com and can hopefully add some more info about the issue.

0

You are true, env allows you to put things into the environment that may not be valid for a shell. I see no problem with this fact as env is a separate program and the environment is not limited to what a shell accepts as shell variables.

Looking a bit closer at the results shows that none of the usual shells behave in a way that results in inaccessible shell variables:

  • Bourne Shell does not import or propagate such variables at all

  • ksh (all versions since ksh88) and zsh just keep the variables in the environment, but do not propagate them to the list of shell variables

The only problematic shell seems to be bash as it imports the environment into the list of shell variables but does not permit to access the related shell variable.

I recommend you to make a bug report against bash.

6
  • So allowing arbitrary name only for other programs access, or is there other purpose? And was it allowed by POSIX? If it's true, so the POSIX documentation was annoyed to me, it said name=var command equivalent to env name=var command.
    – cuonglm
    Commented Oct 2, 2015 at 11:46
  • I cannot see any restriction in the POSIX definition related to the environment that is set up via setenv() or putenv(). Equivalent is not identical. name=var command is completely handled by the shell and you first need to follow shell variable rules. env is a separate command with different rules.
    – schily
    Commented Oct 2, 2015 at 12:07
  • The documentation said The example is equivalent to env when an environment variable is being added to the environment of the command, but not when the environment is being set to the given value. So in env 'BASH_FUNC_foo%%=() { echo foo; }', I added an environment variable BASH_FUNC_foo%% to the environment, but I can not add it with name=var.
    – cuonglm
    Commented Oct 2, 2015 at 12:21
  • 1
    With the latter command you set up a temporary (for one command only) shell variable and auto-export it. You still need to follow the shell rules for shell variables. When you use env, you use a separate program to directly insert an environment variable - no shell internals are involved.
    – schily
    Commented Oct 2, 2015 at 12:39
  • I got it. I mean the POSIX statement was wrong name=value command and env name=value command isn't always equivalent right? Or strictly speaking, they're only equivalent about functional.
    – cuonglm
    Commented Oct 2, 2015 at 12:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .