差別:
指令
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
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
$ 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
#!/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.