为什么我会在命令之前使用env?

jer*_*rzy 4 bash shell

我见过同事前缀(交互式)shell命令env,比如env KEY=value my_script调用my_script.

我的问题是:env在这里使用有什么意义?你为什么不写KEY=value my_script

我明白了什么env,以及使用例如#!/usr/bin/env python完美意义.但是,我不明白为什么你会env在交互式shell中为命令添加前缀.

Kei*_*son 8

有可能是没有很好的理由,为什么你必须使用env在交互式命令.

在Bourne派生的shell(sh,ksh,bash,zsh)中,这两个命令:

key=VALUE my_script
env key=VALUE my_script
Run Code Online (Sandbox Code Playgroud)

基本相同.

不同之处在于,在第一个命令中,它key=Value是shell语法的一部分,而不是执行命令的一部分.env是一个实际的命令(通常不会内置到shell中).因此,您需要使用上下文env,例如,如果您正在运行调用另一个命令的命令.例如,如果您正在使用find-exec选项:

find . -type f -exec some_command \;
Run Code Online (Sandbox Code Playgroud)

然后由shell some_command调用find,而不是由shell 调用,并且key=VALUE不会识别前导.你可以env用来解决这个问题.

但这是一个相当不寻常的情况,并不适用于运行简单的命令.

另一个可能的原因是csh和tcsh shell(不是从Bourne shell派生的)不使用相同的语法.习惯于以交互方式使用csh或tcsh的人可能会习惯于使用env key=Value my_script习惯.

或者有人可能会觉得使用env命令更明确,因此更清晰.

在最坏的情况下,这是一个无害的怪癖.它确实调用了一个额外的进程,效率可能略低,但在一个并不重要的交互式命令中.

正如chepner的评论所指出的那样,该env命令允许您设置名称不是有效的shell变量名称的环境变量(虽然这很少是一个好主意),并且该-i选项允许您在设置变量之前清除现有环境.

(至于#!/usr/bin/env黑客,请参阅此问题我的答案进行讨论.)

  • `env`允许你向环境中添加非有效shell标识符的名称,例如`env'奇怪的名字"= foo bash`.它还提供了一种从子环境中删除*名称的方法,使用`-i`标志以空环境开始,只包含作为`env`参数传递的名称/值对. (2认同)