Environment-Variables

shell 變數可以有哪些作用域?

  • December 15, 2017

我剛剛遇到了一個問題,表明我不清楚 shell 變數的範圍。

我試圖使用bundle install,這是一個 Ruby 命令,它使用 的值$GEM_HOME來完成它的工作。我已經設置$GEM_HOME了,但在我使用之前,該命令忽略了該值export,如export GEM_HOME=/some/path.

我讀到這使得變數以某種方式“全域”(也稱為環境變數),但我不明白這意味著什麼。我知道程式中的全域變數,但不了解不同的程序。

另外,鑑於我設置的此類變數僅適用於目前的 shell 會話,我將如何為守護程序設置它們?

shell 變數可以有哪些作用域?

這些程序被組織成一棵樹:每個程序都有一個唯一的父程序,除此之外init總是PID1 並且沒有父程序。

新程序的創建一般通過一對fork/execv系統呼叫,其中子程序的環境是父程序的副本

要將變數從 shell 放入環境中,您必須使用export該變數,以便所有子級都可以遞歸地看到它。但請注意,如果子項更改變數的值,則更改後的值僅對它可見,並且在該更改之後創建的所有程序(如前所述,是一個副本)。

還要考慮到子程序可能會更改其環境,例如可以將其重置為預設值,例如可能會這樣做login

至少在kshand下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 中您可以使用完全全域且由所有程序共享的系統變數。

引用自:https://unix.stackexchange.com/questions/27555