我时不时地会编写一个 bash 脚本,我发现设置变量有几种方法:
key=value
env key=value
export key=value
当您在脚本或单个命令中时(例如,我经常将变量与 Wine 启动器链接起来以设置正确的 Wine 前缀),它们似乎完全可以互换,但事实肯定不是这样。
这三种方法有什么区别?您能给我举个例子说明何时需要具体使用哪种方法吗?
肯定与`VAR=...` 和 `export VAR=...` 之间有什么区别?但我也想知道如何env
适应这一点,并且一些展示每种方法的好处的例子也很好:)
答案1
让我们考虑一个具体的例子。该grep
命令使用名为的环境变量GREP_OPTIONS
来设置默认选项。
现在。假设文件test.txt
包含以下行:
line one
line two
运行命令grep one test.txt
将返回
line one
如果使用该-v
选项运行 grep,它将返回不匹配的行,因此输出将是
line two
我们现在将尝试使用环境变量来设置选项。
环境变量设置没有
export
将不会在您调用的命令的环境中被继承。GREP_OPTIONS='-v' grep one test.txt
结果:
line one
显然,该选项
-v
没有传递给grep
。当您要设置一个仅供 shell 使用的变量时,您需要使用此形式,例如,
for i in * ; do
您不想导出$i
。但是,该变量会传递到该特定命令行的环境中,因此您可以执行
GREP_OPTIONS='-v' grep one test.txt
这将返回预期
line two
您可以使用此表单暂时更改所启动程序的此特定实例的环境。
导出变量会导致该变量被继承:
export GREP_OPTIONS='-v' grep one test.txt
现在返回
line two
这是在 shell 中为随后启动的进程设置变量的最常用方法
这一切都是在 bash 中完成的。
export
是 bash 内置命令;VAR=whatever
是 bash 语法。env
另一方面, 本身就是一个程序。 当env
被调用时,会发生以下事情:- 该命令
env
作为新进程执行 env
改变环境,并且- 调用作为参数提供的命令。
env
进程被进程替换command
。
例子:
env GREP_OPTIONS='-v' grep one test.txt
此命令将启动两个新进程:(i)env 和(ii)grep(实际上,第二个进程将替换第一个进程)。从进程的角度来看
grep
,结果是确切地和跑步一样GREP_OPTIONS='-v' grep one test.txt
但是,如果您不在 bash 中或者不想启动另一个 shell(例如,当您使用
exec()
函数系列而不是system()
调用时),则可以使用此习语。- 该命令
补充说明#!/usr/bin/env
#!/usr/bin/env interpreter
这也是为什么使用成语而不是的原因#!/usr/bin/interpreter
。env
不需要程序的完整路径,因为它使用像 shell 一样execvp()
搜索PATH
变量的函数,然后取代 命令 run 本身。因此,它可用于找出解释器(如 perl 或 python)在路径上的“位置”。
这也意味着通过修改当前路径,您可以影响将调用哪个 Python 变体。这使得以下操作成为可能:
echo -e '#!/usr/bin/bash\n\necho I am an evil interpreter!' > python
chmod a+x ./python
export PATH=.
python
而不是运行 Python,将导致
I am an evil interpreter!