In Bash shell, I want to sanitize the environment as the first thing when running with a command.
在Bash shell中,我想在使用命令运行时首先清理环境。
I want to unset all the environment variables and only set the ones that are critical for the shell to function, plus the ones the ones needed by my script to complete it's task.
我想取消设置所有环境变量,只设置对shell运行至关重要的变量,以及我的脚本完成它的任务所需的变量。
Is there a way to do this in a simple and clean way?
有没有办法以简单干净的方式做到这一点?
5 个解决方案
#1
31
You can use env
and a wrapper script:
您可以使用env和包装器脚本:
#!/bin/bash
env -i /path/to/main_script.sh
From man env
:
来自man env:
-i, --ignore-environment start with an empty environment
You can also, of course, just run the script as env -i script.sh
if you are running it by hand. Unfortunately as far as I can tell one can't use the script shebang to run bash
through env
like this; the shebang can only accept two parameters by definition as parsed by the kernel.
当然,如果您手动运行脚本,也可以将脚本作为env -i script.sh运行。不幸的是,据我所知,不能使用脚本shebang通过这样的env运行bash; shebang只能接受内核解析的两个参数。
The other semi-reliable solution using env
or exec -c
(which does pretty much the same) that I can think of would be to use exec -c $0
to re-run the script with a clean environment if you detect it's not clean. Assuming $HOME
is set in an unclean environment and is not set in a clean one (that's true in my install):
使用env或exec -c(几乎完全相同)的另一个半可靠解决方案,我能想到的是使用exec -c $ 0在干净的环境中重新运行脚本,如果你发现它不干净的话。假设$ HOME设置在一个不干净的环境中并且没有设置在干净的环境中(在我的安装中这是真的):
#!/bin/bash
[ "$HOME" != "" ] && exec -c $0
# rest of the script here
#2
8
Unset all environment variables bash linux
Command: env -i bash
命令:env -i bash
Example, create local and environment variables, then reset to defaults:
例如,创建本地和环境变量,然后重置为默认值:
el@defiant ~$ LOCAL_DOGE="such variable"
el@defiant ~$ ENVIRONMENT_DOGE="much code"
el@defiant ~$ export ENVIRONMENT_DOGE
el@defiant ~$ set | grep DOGE
ENVIRONMENT_DOGE='much code'
LOCAL_DOGE='such variable'
el@defiant ~$ env | grep DOGE
ENVIRONMENT_DOGE=much code
el@defiant ~$ env -i bash
el@defiant ~$ set | grep DOGE
el@defiant ~$ env | grep DOGE
el@defiant ~$
So wow, LOCAL_DOGE
and ENVIRONMENT_DOGE
are gone with one command.
所以哇,LOCAL_DOGE和ENVIRONMENT_DOGE都没有一个命令。
Unset all environment variables bash linux, alternate way.
env - /bin/bash
Example:
例:
el@defiant ~$ DOGE1="one"
el@defiant ~$ export DOGE2="two"
el@defiant ~$ set | grep DOGE
DOGE1=one
DOGE2=two
el@defiant ~$ env | grep DOGE
DOGE2=two
el@defiant ~$ env - /bin/bash
el@defiant ~$ set | grep DOGE
el@defiant ~$ env | grep DOGE
#3
6
This worked when I tried it:
这在我尝试时起作用了:
for c in $(set | cut -d '=' -f 1); do unset $c; done
It spewed errors on the const variables, but I was able to ignore them.
它在const变量上出现错误,但我能够忽略它们。
#4
2
Expanding on Eduardo's answer:
扩展Eduardo的答案:
$ env -i bash -c 'printf "%s\n" "${?+?=$?}" "${#+#=$#}" "${*+*=$*}" "${@+@=$@}" "${-+-=$-}" "${!+!=$!}" "${_+_=$_}" "${$+$=$$}"; env'
?=0
#=0
-=hB
_=bash
$=26927
PWD=/home/username/INVENTORY
SHLVL=1
_=/usr/bin/env
In other words, the following variables are defined in a script run with env -i
and shown by env
:
换句话说,在使用env -i运行并由env显示的脚本中定义了以下变量:
-
$PWD
(working directory) - $ PWD(工作目录)
-
$SHLVL
(number of shells within shells) - $ SHLVL(shell中的shell数)
-
$_
(final argument of previous command) - $ _(上一个命令的最后一个参数)
The following variables are also defined, but not shown by env
:
还定义了以下变量,但env未显示:
-
$?
(result of last command) - $? (最后一个命令的结果)
-
$#
(number of arguments) - $#(参数个数)
-
$-
(flags passed to the script) - $ - (传递给脚本的标志)
-
$$
(PID of the script) - $$(脚本的PID)
#5
0
I came across this problem while trying to make a helper function to avoid the proxy. I came to call it proxyless
. Its code follows:
我在尝试创建一个帮助函数以避免代理时遇到了这个问题。我来称它为无代理。其代码如下:
proxyless () {
cmd=(unset http_proxy https_proxy \; ${@})
bash -c "${cmd[*]}"
}
What I am doing effectively is building a command array to pass to bash. So, I use unset
to do the obvious, and I put all the command arguments to the end of the array. So, for example,
我正在做的有效的是构建一个命令数组来传递给bash。所以,我使用unset来做显而易见的事情,并将所有命令参数放到数组的末尾。所以,例如,
$ proxyless curl google.com
will become (according to bash -x
)
将成为(根据bash -x)
$ bash -c 'unset http_proxy https_proxy; curl google.com'
#1
31
You can use env
and a wrapper script:
您可以使用env和包装器脚本:
#!/bin/bash
env -i /path/to/main_script.sh
From man env
:
来自man env:
-i, --ignore-environment start with an empty environment
You can also, of course, just run the script as env -i script.sh
if you are running it by hand. Unfortunately as far as I can tell one can't use the script shebang to run bash
through env
like this; the shebang can only accept two parameters by definition as parsed by the kernel.
当然,如果您手动运行脚本,也可以将脚本作为env -i script.sh运行。不幸的是,据我所知,不能使用脚本shebang通过这样的env运行bash; shebang只能接受内核解析的两个参数。
The other semi-reliable solution using env
or exec -c
(which does pretty much the same) that I can think of would be to use exec -c $0
to re-run the script with a clean environment if you detect it's not clean. Assuming $HOME
is set in an unclean environment and is not set in a clean one (that's true in my install):
使用env或exec -c(几乎完全相同)的另一个半可靠解决方案,我能想到的是使用exec -c $ 0在干净的环境中重新运行脚本,如果你发现它不干净的话。假设$ HOME设置在一个不干净的环境中并且没有设置在干净的环境中(在我的安装中这是真的):
#!/bin/bash
[ "$HOME" != "" ] && exec -c $0
# rest of the script here
#2
8
Unset all environment variables bash linux
Command: env -i bash
命令:env -i bash
Example, create local and environment variables, then reset to defaults:
例如,创建本地和环境变量,然后重置为默认值:
el@defiant ~$ LOCAL_DOGE="such variable"
el@defiant ~$ ENVIRONMENT_DOGE="much code"
el@defiant ~$ export ENVIRONMENT_DOGE
el@defiant ~$ set | grep DOGE
ENVIRONMENT_DOGE='much code'
LOCAL_DOGE='such variable'
el@defiant ~$ env | grep DOGE
ENVIRONMENT_DOGE=much code
el@defiant ~$ env -i bash
el@defiant ~$ set | grep DOGE
el@defiant ~$ env | grep DOGE
el@defiant ~$
So wow, LOCAL_DOGE
and ENVIRONMENT_DOGE
are gone with one command.
所以哇,LOCAL_DOGE和ENVIRONMENT_DOGE都没有一个命令。
Unset all environment variables bash linux, alternate way.
env - /bin/bash
Example:
例:
el@defiant ~$ DOGE1="one"
el@defiant ~$ export DOGE2="two"
el@defiant ~$ set | grep DOGE
DOGE1=one
DOGE2=two
el@defiant ~$ env | grep DOGE
DOGE2=two
el@defiant ~$ env - /bin/bash
el@defiant ~$ set | grep DOGE
el@defiant ~$ env | grep DOGE
#3
6
This worked when I tried it:
这在我尝试时起作用了:
for c in $(set | cut -d '=' -f 1); do unset $c; done
It spewed errors on the const variables, but I was able to ignore them.
它在const变量上出现错误,但我能够忽略它们。
#4
2
Expanding on Eduardo's answer:
扩展Eduardo的答案:
$ env -i bash -c 'printf "%s\n" "${?+?=$?}" "${#+#=$#}" "${*+*=$*}" "${@+@=$@}" "${-+-=$-}" "${!+!=$!}" "${_+_=$_}" "${$+$=$$}"; env'
?=0
#=0
-=hB
_=bash
$=26927
PWD=/home/username/INVENTORY
SHLVL=1
_=/usr/bin/env
In other words, the following variables are defined in a script run with env -i
and shown by env
:
换句话说,在使用env -i运行并由env显示的脚本中定义了以下变量:
-
$PWD
(working directory) - $ PWD(工作目录)
-
$SHLVL
(number of shells within shells) - $ SHLVL(shell中的shell数)
-
$_
(final argument of previous command) - $ _(上一个命令的最后一个参数)
The following variables are also defined, but not shown by env
:
还定义了以下变量,但env未显示:
-
$?
(result of last command) - $? (最后一个命令的结果)
-
$#
(number of arguments) - $#(参数个数)
-
$-
(flags passed to the script) - $ - (传递给脚本的标志)
-
$$
(PID of the script) - $$(脚本的PID)
#5
0
I came across this problem while trying to make a helper function to avoid the proxy. I came to call it proxyless
. Its code follows:
我在尝试创建一个帮助函数以避免代理时遇到了这个问题。我来称它为无代理。其代码如下:
proxyless () {
cmd=(unset http_proxy https_proxy \; ${@})
bash -c "${cmd[*]}"
}
What I am doing effectively is building a command array to pass to bash. So, I use unset
to do the obvious, and I put all the command arguments to the end of the array. So, for example,
我正在做的有效的是构建一个命令数组来传递给bash。所以,我使用unset来做显而易见的事情,并将所有命令参数放到数组的末尾。所以,例如,
$ proxyless curl google.com
will become (according to bash -x
)
将成为(根据bash -x)
$ bash -c 'unset http_proxy https_proxy; curl google.com'