3

I have read the linux command env manual, specifically, for the -i option, the manual says:

-i, --ignore-environment # start with an empty environment

What I get is that when -i option is specified, the environment is empty,i.e, no environment variable is there, so the command env -i ls should print something like command not found , but what I see is the command executes successfully. So please explain, do I misunderstand anything?

Tracy
  • 1,988
  • 5
  • 25
  • 36

2 Answers2

2

I think it better to read the source code to find out whether the OS PATH variable persists through a clearing of environment – Tracy

Reading the source code would of course give all information about the matter. But we can also obtain valuable clues by using strace:

>strace -eexecve env -i ls       
execve("/usr/bin/env", ["env", "-i", "ls"], [/* 48 vars */]) = 0
execve("ls", ["ls"], [/* 0 vars */])    = -1 ENOENT (No such file or directory)
execve("/bin/ls", ["ls"], [/* 0 vars */]) = 0

We see that env tries executing "ls" without a path first, which fails, and then tries executing "/bin/ls", which succeeds. We also see it start with an empty environment [/* 0 vars */].

>strace -eexecve env -i foo  
execve("/usr/bin/env", ["env", "-i", "foo"], [/* 48 vars */]) = 0
execve("foo", ["foo"], [/* 0 vars */])  = -1 ENOENT (No such file or directory)
execve("/bin/foo", ["foo"], [/* 0 vars */]) = -1 ENOENT (No such file or directory)
execve("/usr/bin/foo", ["foo"], [/* 0 vars */]) = -1 ENOENT (No such file or directory)
env: foo: No such file or directory

When specifying a non-existent command or a command residing in some other path, we see that env finally tries the /usr/bin/ path, and that's it. So, obviously /bin/ and /usr/bin/ are hardcoded in env, and with -i the command's environment is indeed empty. Another test:

>env -i strace ls
strace: ls: command not found

If ls is to be executed not directly by env -i, but indirectly thru another command, it is not found.

Armali
  • 18,255
  • 14
  • 57
  • 171
  • 1
    This question is quite old, but I would like to bring some precisions to your answer. `/bin` and `/usr/bin` are not "hardcoded in `env`", but returned by default by `confstr(_CS_PATH)`, used by `execvp` which is called by `env` (see `execvp` manpage). – Greg82 Aug 28 '19 at 10:11
0

The environment refers to all of the shell variables you set in your .bashrc and .bash_profile on login. If you're compiling something, you may set the CFLAGS variable. If you've got something installed in a weird directory, you may do an export PATH=$PATH:$HOME/build/bin to allow it to run without specifying its full path.

env -i clears all these user-set variables and gives you a blank environment, so you can, for example, test how a command works if you have none of these extra variables set.

ijustlovemath
  • 703
  • 10
  • 21
  • As per your answer, `env -i` should clear all these user-set variable, including `PATH` varibale, so the shell should not be able to locate where `ls` is, but the result did not match my thoughs. – Tracy Aug 04 '16 at 14:19
  • Including *user additions* to the PATH variable. The base OS PATH variable (and I think everything you setup in /etc/skel) persists through a clearing of environment, so things like /bin, /usr/bin, and /usr/local/bin will persist. – ijustlovemath Aug 04 '16 at 14:23
  • 1
    I think it better to read the source code to find out whether the OS PATH variable persists through a clearing of environment – Tracy Aug 06 '16 at 08:40