set,export和env之间的区别是什么?我应该在何时使用它们?
每隔一段时间我就会抨击一个bash脚本,它让我觉得有几种设置变量的方法:
key=value env key=value export key=value
当你在一个脚本或一个命令中时(例如,我经常用一个Wine启动器链接一个变量来设置正确的Wine前缀),这些似乎是完全可以互换的,但肯定不是这种情况。
这三种方法有什么区别,你能举个例子说明我什么时候才能使用这些方法吗?
绝对与`VAR = …`和`export VAR = …`有什么区别? 但是我想知道env
是如何适应这一点的,一些例子显示每个的好处也会很好:)
让我们考虑一个具体的例子。 grep
命令使用名为GREP_OPTIONS
的环境变量来设置默认选项。
现在。 鉴于文件test.txt
包含以下行:
line one line two
运行命令grep one test.txt
将返回
line one
如果使用-v
选项运行grep,它将返回不匹配的行,因此输出将是
line two
我们现在尝试使用环境变量设置选项。
-
未
export
环境变量将不会在您调用的命令的环境中inheritance。GREP_OPTIONS='-v' grep one test.txt
结果:
line one
显然,选项
-v
没有传递给grep
。当您仅为要使用的shell设置变量时,您希望使用此表单,例如in
for i in * ; do
你不想出口$i
。 -
但是,变量会传递到该特定命令行的环境,因此您可以这样做
GREP_OPTIONS='-v' grep one test.txt
这将返回预期的
line two
您可以使用此表单临时更改此特定启动程序实例的环境。
-
导出变量会导致变量被inheritance:
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
不需要程序的完整路径,因为它使用execvp()
函数,就像shell一样搜索PATH
变量,然后通过命令运行替换它自己。 因此,它可以用于找出解释器(如perl或python)在路径上“坐”的位置。
它还意味着通过修改当前路径,您可以影响将调用哪个python变体。 这使得以下可能:
echo -e '#!/usr/bin/bash\n\necho I am an evil interpreter!' > python chmod a+x ./python export PATH=. calibre
而不是推出Calibre,将导致
I am an evil interpreter!