如何在干净的bash环境中运行程序?


Answers:


127

您可以使用env

env -i your_command

与下面的评论相反,这确实清除了环境,但是并没有阻止your_command设置新变量。特别是,运行外壳程序将导致外壳程序/etc/profile运行,并且外壳程序也可能具有一些内置设置。

您可以使用以下方法进行检查:

env -i env

即擦拭环境,然后打印。输出将为空白。


4
尚未完全清除环境:echo 'echo $PATH' > test.sh && chmod u+x test.sh && env -i test.shprints /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
l0b0 2012年

2
但是,似乎这是你能得到的最接近的-这似乎是一样的变量PATHPWDSHLVL通过猛砸自动设置。+1。
l0b0 2012年

3
@ I0b0:看看我的编辑。
ams 2012年

3
第一个评论者脚本中的PATH变量不在环境中,因此不是环境变量。如果没有导出Bash,则Bash显然会设置自己的常规Shell变量PATH: env -i bash --norc -c "declare -p PATH"Give declare -- PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."。如果您自己导出,请注意导出的“ -x”(以及环境的一部分):env -i bash --norc -c "export PATH; declare -p PATH"declare -x PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."
Binary Phile

33

bash可能会有一个“干净”的环境

$ env -i bash --noprofile --norc
  • env -i命令将在命令行上执行给它的命令,而不会将旧Shell环境的任何导出的环境变量传输到已执行程序的环境。

  • --noprofile选项停止bash读取系统范围或个人外壳初始化脚本,否则将为登录外壳读取该脚本。

  • --norc选项停止bash读取个人外壳初始化脚本,否则将为交互式外壳读取该脚本。


我的环境无法识别这些选项。
Paulo Carvalho

@PauloCarvalho您的系统不支持env -i?您在什么系统上?
Kusalananda

抱歉,它在外壳中有效。我试图将其放入脚本中,并以某种方式抛出错误。
Paulo Carvalho

@PauloCarvalho对不起,我看不到您键入的命令或错误。
Kusalananda

太好了-正是我想要的东西。env清理我的环境,--noprofile避免采购/ etc / profile和朋友,并--norc避免采购〜/ .bashrc和朋友。
费利佩·阿尔瓦雷斯

28

env -i somecommandams所述,在空环境中运行命令。

许多程序依赖于一些重要的环境变量,因此您可能需要保留它们:

env -i HOME="$HOME" LC_CTYPE="${LC_ALL:-${LC_CTYPE:-$LANG}}" PATH="$PATH" USER="$USER" somecommand

或者,您可以登录到小型登录时间环境。

ssh localhost somecommand

1
在cmdline上运行命令时有效。我怎么把它放在shebang ?,似乎不起作用
巴尔基

奇怪,我env不支持--定界,并且env -i FOO=bar -- env尝试运行名为的命令--
antak

@antak env -i -- FOO=bar env实际上应该是。我的错。并不是--有用的,因为后面的内容并非以开头-
吉尔斯

没意识到您总是可以ssh进入localhost,这有点奇怪。那里的用例是什么。
Edgar Aroutiounian

@EdgarAroutiounian如果运行的是SSH服务器,则可以SSH到localhost。程序员为什么要努力避免这种情况?
吉尔斯

4

尽管接受的答案是正确的,但是您通常要做的是:

env -i bash -l -c "printenv; and any other commands"

这为您提供了无用但实用的功能(与在非交互模式下登录时所获得的功能相同)。例如,这可以设置语言,时区,HOME等。


那不是很有效,因为env -iclears HOME,这意味着bash -l找不到您的.bash_profile等等。如果您想要的shell类似于您在全新登录时所获得的外壳,则需要HOME首先设置一个额外的间接寻址。
Elliott Slaughter


1

这里大多数答案的问题是env -iclear HOME,因此即使您bash -l在内部运行,它也不会读取您的内容.bash_profile。如果您要寻找的是一个外壳,其作用就像您刚刚进行了新登录一样,想要这个代替:

env -i HOME="$HOME" bash -l -c 'your_command'

例:

$ export ABC=123
$ env -i HOME="$HOME" bash -l -c 'env' | grep ABC
$ env HOME="$HOME" bash -l -c 'env' | grep ABC
ABC=123

1
请注意,登录bash外壳程序将运行.bash_login.bash_profile。要获得一个干净的环境,请使用--noprofile或将其设置HOME为不包含那些文件的目录。我想这取决于您所说的“干净”。
库萨兰达

1
是的,如果您想要一个几乎没有任何东西的外壳,只需按照原始答案执行即可env -i bash -c ...。特别是当您想要一个看起来像刚在计算机上重新登录的shell时,此答案才有用。
Elliott Slaughter

0

要回答balki的评论(并在此过程中回答我自己的问题:-):

% echo Environment in calling shell: vars: $(env |wc -l); echo; ./du; echo; cat du
Environment in calling shell: vars: 43

==> This is the environment: vars: 5
PATH="$PATH"
PWD=/Users/nick
SHLVL=1
SOMETHING_TO_KEEP="$USER"
_=/usr/bin/env
==> The end.

#!/usr/bin/env -i SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh

echo "==> This is the environment: vars:" $(/usr/bin/env | /usr/bin/wc -l)
/usr/bin/env
echo "==> The end."

当我在CentOS 7.6的shebang行中尝试此操作时,我从环境中收到此错误:/usr/bin/env: invalid option -- ' ' Try '/usr/bin/env --help' for more information.
ScottJ

如果我更改脚本以使用long参数,--ignore-environment则会得到以下信息:/usr/bin/env: unrecognized option '--ignore-environment SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh' Try '/usr/bin/env --help' for more information.
ScottJ
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.