简体   繁体   中英

which PATH environment does “exec env - ” use?

please see two commands:

$ export PATH="/bin"

$ exec env - /bin/bash -c 'echo $PATH'

the result is :

/usr/local/bin:/usr/bin

why ?? how can I modify the PATH variable used in "exec env -"

The - option to env clears the environment (therefore the exported PATH gets thrown away). When bash starts up it will perform its normal startup file processing (which probably isn't very much since the -c option specifies a non-interactive shell).

So bash starts up with no PATH in its environment and likely doesn't get one set by a startup file, so it will use a default value. I think that's what you're seeing.

If you're unable to modify the env - command (as you mention in some comments), then to get the PATH you want you'll need to convince bash to execute a startup file that sets the PATH to what you're looking for.

The following is an indication that you might be out of luck since I don't see any startup files being opened by bash :

$ (strace env - /bin/bash -c 'echo $PATH') 2>&1 | grep -E 'open|exec'
execve("/usr/bin/env", ["env", "-", "/bin/bash", "-c", "echo $PATH"], [/* 48 vars */]) = 0
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
execve("/bin/bash", ["/bin/bash", "-c", "echo $PATH"], [/* 0 vars */]) = 0
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libtinfo.so.5", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/dev/tty", O_RDWR|O_NONBLOCK)     = 3
open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libnss_compat.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libnsl.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libnss_nis.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/etc/passwd", O_RDONLY|O_CLOEXEC) = 3

env runs a program in an optionally modified environment. By default, no modifications are made. To modify the environment, you can pass - (as your command does) or -i to remove all existing environment variables and start fresh, and/or pass key=value pairs on the command line to set new values. The latter is the situation you desire:

$ env - PATH="/bin" /bin/bash -c 'echo $PATH'
/bin

Per the man page:

NAME
env - run a program in a modified environment

SYNOPSIS
env [OPTION]... [-] [NAME=VALUE]... [COMMAND [ARG]...]

DESCRIPTION
Set each NAME to VALUE in the environment and run COMMAND.


Since you cannot modify the command, and the command uses - to clear the environment, and the command is bash -c you are out of luck. Here's why:

-c means to execute the given string as a single command. In that mode, normal startup files are not executed. The only way to get a startup file executed in that mode is to set the BASH_ENV variable . However, that won't work in this case because of the env - , which clears all env.

The PATH you see is a Bash variable - not an environment variable .

We can demonstrate this using printenv or export (I've piped through cut to show just the names and not the values):

$ env - bash -c printenv | cut -d= -f1
PWD
SHLVL
_

There are many more (non-exported) Bash variables:

$ env - bash -c set | cut -d= -f1
BASH
BASHOPTS
BASH_ALIASES
BASH_ARGC
BASH_ARGV
BASH_CMDS
BASH_EXECUTION_STRING
BASH_LINENO
BASH_SOURCE
BASH_VERSINFO
BASH_VERSION
DIRSTACK
EUID
GROUPS
HOSTNAME
HOSTTYPE
IFS
MACHTYPE
OPTERR
OPTIND
OSTYPE
PATH
PPID
PS4
PWD
SHELL
SHELLOPTS
SHLVL
TERM
UID
_

(Note that with no $HOME , our user startup scripts are not run; you could add --norc to exclude /etc/bash.bashrc and the like, too).


If you use a different shell, you'll get a different set of default variables:

$ env - dash -c set | cut -d= -f1
IFS
OPTIND
PATH
PPID
PS1
PS2
PS4
PWD
$ env - dash -c printenv | cut -d= -f1
PWD

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