set、export 和 env 之间有什么区别以及我应该何时使用它们?

set、export 和 env 之间有什么区别以及我应该何时使用它们?

我时不时地会编写一个 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

我们现在将尝试使用环境变量来设置选项。

  1. 环境变量设置没有export将不会在您调用的命令的环境中被继承。

    GREP_OPTIONS='-v'
    grep one test.txt
    

    结果:

    line one
    

    显然,该选项-v没有传递给grep

    当您要设置一个仅供 shell 使用的变量时,您需要使用此形式,例如,for i in * ; do您不想导出$i

  2. 但是,该变量会传递到该特定命令行的环境中,因此您可以执行

    GREP_OPTIONS='-v' grep one test.txt
    

    这将返回预期

    line two
    

    您可以使用此表单暂时更改所启动程序的此特定实例的环境。

  3. 导出变量会导致该变量被继承:

    export GREP_OPTIONS='-v'
    grep one test.txt
    

    现在返回

    line two
    

    这是在 shell 中为随后启动的进程设置变量的最常用方法

  4. 这一切都是在 bash 中完成的。export是 bash 内置命令;VAR=whatever是 bash 语法。env另一方面, 本身就是一个程序。 当env被调用时,会发生以下事情:

    1. 该命令env作为新进程执行
    2. env改变环境,并且
    3. 调用作为参数提供的命令。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/interpreterenv不需要程序的完整路径,因为它使用像 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!

相关内容