区别:
命令set
,env
,export
均在 bash
中执行。set
: 改变 shell 属性和定位参数值; 显示本地变量、当前shell 的变量,包括当前用户变量 export
是bash
的内建指令;显示和设置环境变量。VAR=whatever
是变量定义的bash
语法; env
显示环境变量,显示当前用户变量;本身是一个程序,当env
被调用/执行时,实际触发以下过程:
-
命令
env
作为一个新的进程被执行-
env
修改环境 - 调用被用作参数的命令(
command
),env
进程被命令(command
)进程取代
举例:
-
[arthur@localhost blog]$ env GREP_OPTIONS='-v' grep one test.txt
grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
#this is the test file to analyse the difference between env,set and export
line two
上述命令将启动两个新的进程:(i) env 和 (ii) grep (事实上第二个进程会取代第一个进程)。从grep
进程的角度来看,命令执行的结果等同于:
$ GREP_OPTIONS='-v' grep one test.txt
然而,如果你在 bash 之外或者不想启动另一个 shell ,可以使用这个习惯用法(例如,当你使用exec()系列函数而不是system()调用时)
场景:
命令grep
使用称为GREP_OPTIONS
的环境变量来设置命令默认选项。
1. 创建测试文件 test.txt
[arthur@localhost blog]$ vi test.txt
[arthur@localhost blog]$ cat test.txt
#this is the test file to analyse the difference between env,set and export
line one
line two
2. 运行grep
命令
$ grep --help
Usage: grep [OPTION]... PATTERN [FILE]...
Search for PATTERN in each FILE.
Example: grep -i 'hello world' menu.h main.c
-v, --invert-match select non-matching lines
[arthur@localhost blog]$ grep one test.txt
line one
[arthur@localhost blog]$ grep -v one test.txt
#this is the test file to analyse the difference between env,set and export
line two
3. 使用环境变量设置选项:
3.1 若不使用export
命令,设置环境变量时,该变量将不能被继承
[arthur@localhost blog]$ GREP_OPTIONS='-v'
[arthur@localhost blog]$ grep one test.txt
line one
可以发现,选项 -v
并没有传递给命令grep
。
使用场景:当你设置一个变量仅仅是为了供shell
使用的时候,你可以用上述变量命名方式。例如,当你仅仅是为了实现以下功能时:for i in *;do
, 你并不想使用export $i
来设置变量。
3.2 传递变量至特定的命令行环境
[arthur@localhost blog]$ GREP_OPTIONS='-v' grep one test.txt
grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
#this is the test file to analyse the difference between env,set and export
line two
使用场景: 临时性改变所启动程序的特定实例的环境
3.3 使用export
命令使变量可被子程序继承
[arthur@localhost blog]$ export GREP_OPTIONS='-v'
[arthur@localhost blog]$ grep one test.txt
grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
#this is the test file to analyse the difference between env,set and export
line two
使用场景: 为shell 中随后启动的进程设置变量的最常见方法
拓展: #!/usr/bin/env
env
不需要全路径指向一个程序,是因为它使用execvp()
函数,这个函数类似shell
的工作原理,通过PATH
变量来寻找路径,然后,用命令的运行来取代自身。因此,它可以用于找出解释器(如 perl 或者 python)在路径 中的位置。因而经常使用 #!/usr/bin/env interpreter
而不是 #!/usr/bin/interpreter
此外, 通过修改当前路径,可以影响到具体哪个 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!
reference:
[1] what's the difference between set,export, and env and when should I use each ?.stackExchange.