当前位置: 首页>>技术教程>>正文


set,export和env之间有什么区别,我应该在什么时候使用它们?

, ,

问题描述

每隔一段时间我都会打出一个bash脚本,它让我想起了一些设置变量的方法:

key=value
env key=value
export key=value

当你在一个脚本或一个命令中时(例如,我会经常用一个Wine发射器链接一个变量来设置正确的Wine前缀),这些似乎是完全可以互换的,但肯定不能这样。

这三种方法之间的区别是什么?你能给我一个例子,说明什么时候我特别想使用每一种方法?

绝对与What is the difference between `VAR=…` and `export VAR=…`?相关,但我想知道env如何适用于此,并且一些示例显示每个的好处也会很好:)

最佳解决办法

让我们考虑一个具体的例子。 grep命令使用名为GREP_OPTIONS的环境变量来设置默认选项。

现在。鉴于文件test.txt包含以下行:

line one
line two

运行命令grep one test.txt将返回

line one

如果使用-v选项运行grep,它将返回non-matching行,因此输出将会是

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不需要程序的完整路径,因为它使用execvp()函数,它像shell一样搜索PATH变量,然后用run命令替换它自己。因此,它可以用来找出路径上的解释器(如perl或python)”sits”的位置。

这也意味着通过修改当前路径,您可以影响将调用哪个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!

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/808.html,未经允许,请勿转载。