shell 變數可以有哪些作用域?
我剛剛遇到了一個問題,表明我不清楚 shell 變數的範圍。
我試圖使用
bundle install
,這是一個 Ruby 命令,它使用 的值$GEM_HOME
來完成它的工作。我已經設置$GEM_HOME
了,但在我使用之前,該命令忽略了該值export
,如export GEM_HOME=/some/path
.我讀到這使得變數以某種方式“全域”(也稱為環境變數),但我不明白這意味著什麼。我知道程式中的全域變數,但不了解不同的程序。
另外,鑑於我設置的此類變數僅適用於目前的 shell 會話,我將如何為守護程序設置它們?
shell 變數可以有哪些作用域?
這些程序被組織成一棵樹:每個程序都有一個唯一的父程序,除此之外
init
總是PID
1 並且沒有父程序。新程序的創建一般通過一對
fork
/execv
系統呼叫,其中子程序的環境是父程序的副本。要將變數從 shell 放入環境中,您必須使用
export
該變數,以便所有子級都可以遞歸地看到它。但請注意,如果子項更改變數的值,則更改後的值僅對它可見,並且在該更改之後創建的所有程序(如前所述,是一個副本)。還要考慮到子程序可能會更改其環境,例如可以將其重置為預設值,例如可能會這樣做
login
。
至少在
ksh
and下bash
,變數可以有三個範圍,而不是像所有剩餘答案目前所說的那樣有兩個。除了導出的(即環境)變數和shell 未導出的變數範圍之外,還有第三個更窄的函式局部變數範圍。
在帶有標記的 shell 函式中聲明的變數
typeset
僅在它們聲明的函式中以及從那裡呼叫的(子)函式中可見。這個
ksh
/bash
程式碼:# Create a shell script named /tmp/show that displays the scoped variables values. echo 'echo [$environment] [$shell] [$local]' > /tmp/show chmod +x /tmp/show # Function local variable declaration function f { typeset local=three echo "in function": . /tmp/show } # Global variable declaration export environment=one # Unexported (i.e. local) variable declaration shell=two # Call the function that creates a function local variable and # display all three variable values from inside the function f # Display the three values from outside the function echo "in shell": . /tmp/show # Display the same values from a subshell echo "in subshell": /tmp/show # Display the same values from a disconnected shell (simulated here by a clean environment start) echo "in other shell" env -i /tmp/show
產生這個輸出:
in function: [one] [two] [three] in shell: [one] [two] [] in subshell: [one] [] [] in other shell [] [] []
如您所見,導出的變數從前三個位置顯示,未導出的變數不顯示在目前 shell 之外,函式局部變數在函式本身之外沒有值。最後一個測試根本沒有顯示任何值,這是因為導出的變數在 shell 之間不共享,即它們只能被繼承,並且繼承的值以後不會受到父 shell 的影響。
請注意,後一種行為與 Windows 完全不同,在 Windows 中您可以使用完全全域且由所有程序共享的系統變數。