Linux 使用命令或 bash 脚本清理环境?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9671027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sanitize environment with command or bash script?
提问by Otto Ulec
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?
有没有办法以简单而干净的方式做到这一点?
回答by chrisaycock
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 变量上产生错误,但我能够忽略它们。
回答by Eduardo Ivanec
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
-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
手动运行脚本一样运行脚本。不幸的是,据我可以告诉一个不能使用脚本家当运行bash
通过env
这样的; 根据内核解析的定义,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
or exec -c
(其作用几乎相同)的半可靠解决方案是,exec -c $0
如果您检测到它不干净,则使用干净的环境重新运行脚本。假设$HOME
设置在不干净的环境中并且没有设置在干净的环境中(在我的安装中是这样):
#!/bin/bash
[ "$HOME" != "" ] && exec -c $ env -i bash -c 'printf "%s\n" "${?+?=$?}" "${#+#=$#}" "${*+*=$*}" "${@+@=$@}" "${-+-=$-}" "${!+!=$!}" "${_+_=$_}" "${$+$=$$}"; env'
?=0
#=0
-=hB
_=bash
$=26927
PWD=/home/username/INVENTORY
SHLVL=1
_=/usr/bin/env
# rest of the script here
回答by l0b0
Expanding on Eduardo's answer:
扩展爱德华多的回答:
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 ~$
In other words, the following variables are defined in a script run with env -i
andshown by env
:
换句话说,下面的变量是在与脚本运行定义env -i
和所示env
:
$PWD
(working directory)$SHLVL
(number of shells within shells)$_
(final argument of previous command)
$PWD
(工作目录)$SHLVL
(壳内壳数)$_
(上一个命令的最后一个参数)
The following variables are alsodefined, but notshown by env
:
以下变量也是定义,但没有被显示env
:
$?
(result of last command)$#
(number of arguments)$-
(flags passed to the script)$$
(PID of the script)
$?
(最后一个命令的结果)$#
(参数数量)$-
(传递给脚本的标志)$$
(脚本的PID)
回答by Eric Leschinski
Unset all environment variables bash linux
取消设置所有环境变量 bash linux
Command: env -i bash
命令: env -i bash
Example, create local and environment variables, then reset to defaults:
例如,创建本地和环境变量,然后重置为默认值:
env - /bin/bash
So wow, LOCAL_DOGE
and ENVIRONMENT_DOGE
are gone with one command.
所以,哇,LOCAL_DOGE
并且ENVIRONMENT_DOGE
都走了一个命令。
Unset all environment variables bash linux, alternate way.
取消设置所有环境变量 bash linux,替代方法。
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
Example:
例子:
proxyless () {
cmd=(unset http_proxy https_proxy \; ${@})
bash -c "${cmd[*]}"
}
回答by PEdroArthur
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
。其代码如下:
$ proxyless curl google.com
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
做显而易见的事情,并将所有命令参数放在数组的末尾。所以,例如,
$ bash -c 'unset http_proxy https_proxy; curl google.com'
will become (according to bash -x
)
将成为(根据bash -x
)
while IFS='=' read -rd '' name value ; do unset "$name" ; done < /proc/self/environ
回答by Vladimir Panteleev
Here is a way to do this without starting a new shell, and that will work even with weird variable names (containing whitespace/newlines):
这是一种无需启动新外壳即可执行此操作的方法,即使使用奇怪的变量名称(包含空格/换行符)也可以使用:
##代码##The disadvantage is that it is Linux-specific, and relies on procfs being mounted.
缺点是它是 Linux 特定的,并且依赖于安装的 procfs。
This will unset allenvironment variables, even HOME
and PATH
. This may or may not be what you want.
这将取消设置所有环境变量,甚至HOME
和PATH
. 这可能是也可能不是您想要的。
Explanation: /proc/PID/environ
contains the process's environment block, as a series of zero-delimited NAME=VALUE
strings. We use a read
loop, setting the field separator IFS
to =
so that we can split the name and value from each string. By setting the line delimiter (-d
) to an empty string, we cause read
to use the null character (the "first" character of a null-terminated string) to split lines. Then, just unset each name in turn (taking care to quote it).
说明:/proc/PID/environ
包含进程的环境块,作为一系列以零分隔的NAME=VALUE
字符串。我们使用一个read
循环,将字段分隔符设置为IFS
,=
以便我们可以从每个字符串中拆分名称和值。通过将行分隔符 ( -d
) 设置为空字符串,我们read
可以使用空字符(以空字符结尾的字符串的“第一个”字符)来分割行。然后,依次取消设置每个名称(注意引用它)。