简体   繁体   中英

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 (ie 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 i gnored, but this seems inconsistent with env - echo $PATH printing my environment's PATH .)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM