fuzzybear3965
fuzzybear3965

Reputation: 263

Why does `env -i` fail to ignore my environment?

Acknowledgement: Maybe I'm misunderstanding what "environment" means.

The man page for env claims that env - [command] (or env -i [command]) should run command in an empty environment. Testing this behavior, PATH is an environment variable (i.e. a part of an "environment"). But, alas:

➜  ~ env - echo $PATH
/home/user/.nvm/versions/node/v15.3.0/bin:/home/user/.deno/bin:/usr/local/lib/node/nodejs/bin:/home/user/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

is the same as

➜  ~ echo $PATH
/home/user/.nvm/versions/node/v15.3.0/bin:/home/user/.deno/bin:/usr/local/lib/node/nodejs/bin:/home/user/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

So, what's going on? This happens for a few other environment variables, too, like $SHELL and $USER.

So, can someone define "environment" and what env actually does when using env - [command] or env -i [command].

Note that env - PATH= echo $PATH produces the expected result of failing to find echo on the path. But, it's weird to me that I have to explicitly set that environment variable to an empty string since I'm ostensibly clearing my environment prior to running [command].

Bonus confusion:

env env prints all of my environment's variables while env - env produces empty output (makes sense... environment should be ignored, but this seems inconsistent with env - echo $PATH printing my environment's PATH.)

Upvotes: 1

Views: 736

Answers (1)

johannes
johannes

Reputation: 381

In env -i echo $PATH, the variable is expanded by your shell, so the env program never sees the variable.

You can spawn a child shell to inspect variables; use quotes to prevent evaluation by the parent shell:

A=1 env -i sh -c 'echo $A' # prints nothing
A=1 env    sh -c 'echo $A' # prints 1
A=1 env    printenv A      # prints 1

PATH is special. Even if you delete it from your environment, your shell will probably define a fallback path. That one is not exported to child processes but only visible as shell variable.

env -i printenv PATH       # prints nothing, PATH is no longer exported
env -i sh -c 'echo $PATH'  # prints something like /sbin:/bin

Upvotes: 6

Related Questions