使用命令或bash脚本清理环境?

时间:2012-03-12 16:32:26

标签: linux bash

在Bash shell中,我想在使用命令运行时首先清理环境。

我想取消设置所有环境变量,只设置对shell起作用的关键变量,以及我的脚本完成任务所需的那些变量。

有没有办法以简单干净的方式做到这一点?

6 个答案:

答案 0 :(得分:38)

您可以使用env和包装脚本:

#!/bin/bash
env -i /path/to/main_script.sh

来自man env

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

当然,如果您手动运行脚本,也可以将脚本作为env -i script.sh运行。不幸的是,据我所知,不能使用脚本shebang来运行bashenv这样;根据内核解析,shebang只能接受两个参数。

使用envexec -c(几乎完全相同)的其他半可靠解决方案,我能想到的是使用exec -c $0重新运行脚本一个干净的环境,如果你发现它不干净。假设$HOME设置在一个不干净的环境中并且未设置为干净的(在我的安装中是真的):

#!/bin/bash
[ "$HOME" != "" ] && exec -c $0
# rest of the script here

答案 1 :(得分:10)

取消设置所有环境变量bash linux

命令:env -i bash

示例,创建本地和环境变量,然后重置为默认值:

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 ~$

哇,LOCAL_DOGEENVIRONMENT_DOGE只用了一个命令。

取消设置所有环境变量bash linux,替代方式。

env - /bin/bash

示例:

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

答案 2 :(得分:5)

这在我尝试时起作用了:

for c in $(set | cut -d '=' -f 1); do unset $c; done

它在const变量上出现错误,但我能够忽略它们。

答案 3 :(得分:2)

这是一种无需启动新shell即可执行此操作的方法,即使使用奇怪的变量名(包含空格/换行符),该方法也可以使用:

while IFS='=' read -rd '' name value ; do unset "$name" ; done < /proc/self/environ

缺点是它特定于Linux,并且依赖于挂载的procfs。

这将取消设置所有环境变量,甚至HOMEPATH。这可能是您想要的,也可能不是。

说明:/proc/PID/environ包含进程的环境块,为一系列以零分隔的NAME=VALUE字符串。我们使用read循环,将字段分隔符IFS设置为=,以便我们可以从每个字符串中拆分名称和值。通过将行定界符(-d)设置为空字符串,我们使read使用空字符(以空终止的字符串的“第一个”字符)来分割行。然后,只需依次取消设置每个名称(注意将其引用)。

答案 4 :(得分:1)

扩展Eduardo's answer

$ env -i bash -c 'printf "%s\n" "${?+?=$?}" "${#+#=$#}" "${*+*=$*}" "${@+@=$@}" "${-+-=$-}" "${!+!=$!}" "${_+_=$_}" "${$+$=$$}"; env'
?=0
#=0

-=hB

_=bash
$=26927
PWD=/home/username/INVENTORY
SHLVL=1
_=/usr/bin/env

换句话说,以env -i显示的env 运行的脚本中定义了以下变量:

  • $PWD(工作目录)
  • $SHLVL(shell中的shell数量)
  • $_(上一个命令的最后一个参数)

以下变量定义,但env显示

  • $?(上一个命令的结果)
  • $#(参数数量)
  • $-(传递给脚本的标志)
  • $$(脚本的PID)

答案 5 :(得分:0)

我在尝试创建辅助函数以避免代理时遇到了这个问题。我来称它为proxyless。其代码如下:

proxyless () {
  cmd=(unset http_proxy https_proxy \; ${@})
  bash -c "${cmd[*]}"
}

我正在有效地做的是构建一个命令数组以传递给bash。所以,我使用unset做了显而易见的事情,并将所有命令参数放在数组的末尾。所以,例如,

$ proxyless curl google.com

将成为(根据bash -x

$ bash -c 'unset http_proxy https_proxy; curl google.com'