让我们考虑一个具体的例子。该grep
命令使用称为的环境变量GREP_OPTIONS
来设置默认选项。
现在。鉴于该文件test.txt
包含以下几行:
line one
line two
运行命令grep one test.txt
将返回
line one
如果使用该-v
选项运行grep ,它将返回不匹配的行,因此输出为
line two
现在,我们将尝试使用环境变量来设置选项。
设置export
为no的环境变量将不会在您正在调用的命令的环境中继承。
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
不需要程序的完整路径,因为它使用的execvp()
功能PATH
就像shell一样搜索变量,然后 由运行命令替换它。因此,它可以用来找出解释器(如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!
export key=value
是扩展语法,不应在可移植脚本(即#! /bin/sh
)中使用。