天天看點

執行個體分析:Linux 系統 CentOS8 shell 中 set, env, export 差別與使用場景

差別:

指令

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.