shell變數和環境變數在用法上有什麼區別?
我實際上不知道我可以從命令行訪問兩種不同類型的變數。我所知道的是,我可以聲明如下變數:
foo="my dear friends" bar[0]="one" bar[1]="two" bar[2]="three"
或使用 $ 符號訪問它們,例如:
echo $foo echo ${bar[1]}
或使用內置變數,例如:
echo $PWD PATH=$PATH:"/usr/bin/myProg"
現在,我聽說有兩種(至少?)變數類型:shell 變數和環境變數。
- 擁有兩種不同類型的目的是什麼?
- 我怎麼知道變數是哪種類型?
- 每種的典型用法是什麼?
環境變數是
name=value
存在於任何程序(shell、應用程序、守護程序……)中的對的列表。它們通常由子程序繼承(由fork
/exec
序列創建):子程序獲得自己的父變數副本。Shell 變數確實只存在於 shell 的上下文中。它們僅在子shell 中繼承(即當shell 沒有
exec
操作被分叉時)。根據 shell 特性,變數可能不僅是簡單的字元串(如環境變數),還可能是數組、複合變數、類型變數(如整數或浮點數等)。當 shell 啟動時,它從其父級繼承的所有環境變數也成為 shell 變數(除非它們作為 shell 變數和其他極端情況無效,如
IFS
某些 shell 重置),但這些繼承的變數被標記為 export 1。這意味著它們將保持可用於具有由 shell 設置的潛在更新值的子程序。export
在 shell 下創建變數並用關鍵字標記為導出的情況也是如此。數組和其他復雜類型變數不能被導出,除非它們的名稱和值可以轉換為
name=value
模式,或者當有特定於 shell 的機制時(例如:bash
導出環境中的函式和一些異國情調的非 POSIX shell,例如rc
並且es
可以導出數組)。因此,環境變數和 shell 變數之間的主要區別在於它們的作用域:環境變數是全域的,而非導出的 shell 變數是腳本的本地變數。
另請注意,現代 shell(至少
ksh
andbash
)支持第三個 shell 變數範圍。使用關鍵字在函式中創建的變數是該函式的typeset
局部變數(聲明函式的方式在 下啟用/禁用此功能,並且持久性行為在和ksh
之間是不同的)。見https://unix.stackexchange.com/a/28349/2594bash``ksh
1這適用於現代 shell,如、
ksh
和類似的。傳統的 Bourne shell 和非 Bourne 語法 shell具有不同的行為。dash``bash``csh
外殼變數
Shell 變數是作用域在目前 shell 會話中的變數,例如在互動式 shell 會話或腳本中。
您可以通過為未使用的名稱分配值來創建 shell 變數:
var="hello"
shell 變數的使用是為了跟踪目前會話中的數據。Shell 變數的名稱通常帶有小寫字母。
環境變數
環境變數是已導出的 shell 變數。這意味著它將作為變數可見,不僅在創建它的 shell 會話中,而且對於從該會話啟動的任何程序(不僅僅是 shell)也是可見的。
VAR="hello" # shell variable created export VAR # variable now part of the environment
或者
export VAR="hello"
一旦一個 shell 變數被導出,它就會一直被導出,直到它被取消設置,或者直到它的“導出屬性”被刪除(使用
export -n
inbash
),所以通常不需要重新導出它。取消設置變數unset
會刪除它(無論它是否是環境變數)。數組和關聯散列在
bash
和其他 shell 中可能不會被導出為環境變數。環境變數必須是簡單的變數,其值為字元串,並且它們的名稱通常由大寫字母組成。環境變數的使用是為了跟踪目前 shell 會話中的數據,同時也允許任何啟動的程序獲取該數據的一部分。典型的情況是
PATH
環境變數,它可以在 shell 中設置,然後由任何想要啟動程序而不指定它們的完整路徑的程序使用。程序中環境變數的集合通常被稱為“程序的環境”。每個程序都有自己的環境。
環境變數只能“轉發”,即子程序永遠不能更改其父程序中的環境變數,並且除了在啟動子程序時為子程序設置環境外,父程序不能更改子程序的現有環境子程序。
環境變數可以與
env
(不帶任何參數)一起列出。除此之外,它們看起來與 shell 會話中的非導出 shell 變數相同。這對於 shell 來說有點特殊,因為大多數其他程式語言通常不會將“普通”變數與環境變數混合(見下文)。
env
也可用於在程序的環境中設置一個或多個環境變數的值,而無需在目前會話中設置它們:env CC=clang CXX=clang++ make
這首先
make
將環境變數CC
設置為 valueclang
並CXX
設置為clang++
.它也可用於清除程序的環境:
env -i bash
這會啟動
bash
但不會將目前環境轉移到新bash
程序(它仍然具有環境變數,因為它會從其 shell 初始化腳本創建新環境變數)。差異範例
$ var="hello" # create shell variable "var" $ bash # start _new_ bash session $ echo "$var" # no output $ exit # back to original shell session $ echo "$var" # "hello" is outputted $ unset var # remove variable $ export VAR="hello" # create environment variable "VAR" $ bash $ echo "$VAR" # "hello" is outputted since it's exported $ exit # back to original shell session $ unset VAR # remove variable $ ( export VAR="hello"; echo "$VAR" ) # set env. var "VAR" to "hello" in subshell and echo it $ echo "$VAR" # no output since a subshell has its own environment
其他語言
大多數程式語言中都有允許獲取和設置環境變數的庫函式。請注意,由於環境變數儲存為簡單的鍵值關係,它們通常不是語言的“變數”。程序可能會獲取與鍵(環境變數的名稱)相對應的值(始終是字元串),但隨後必須將其轉換為整數或語言期望值具有的任何數據類型。
在 C 中,可以使用
getenv()
、setenv()
和訪問環境變數。C 程序啟動的任何程序都以相同的方式繼承使用這些常式創建的變數。putenv()``unsetenv()
其他語言可能有特殊的資料結構來完成同樣的事情,比如
%ENV
Perl 中的雜湊,或者ENVIRON
大多數awk
.