Shell變數的作用域:Shell全域性變數、環境變數和區域性變數

2020-07-16 10:04:46
Shell 變數的作用域(Scope),就是 Shell 變數的有效範圍(可以使用的範圍)。

在不同的作用域中,同名的變數不會相互干涉,就好像 A 班有個叫小明的同學,B 班也有個叫小明的同學,雖然他們都叫小明(對應於變數名),但是由於所在的班級(對應於作用域)不同,所以不會造成混亂。但是如果同一個班級中有兩個叫小明的同學,就必須用類似於“大小明”、“小小明”這樣的命名來區分他們。

Shell 變數的作用域可以分為三種:
  • 有的變數只能在函數內部使用,這叫做區域性變數(local variable)
  • 有的變數可以在當前 Shell 進程中使用,這叫做全域性變數(global variable)
  • 而有的變數還可以在子進程中使用,這叫做環境變數(environment variable)

Shell 區域性變數

Shell 也支援自定義函數,但是 Shell 函數和 C++、Java、C# 等其他程式語言函數的一個不同點就是:在 Shell 函數中定義的變數預設也是全域性變數,它和在函數外部定義變數擁有一樣的效果。請看下面的程式碼:
#!/bin/bash

#定義函數
function func(){
    a=99
}

#呼叫函數
func

#輸出函數內部的變數
echo $a
輸出結果:
99

a 是在函數內部定義的,但是在函數外部也可以得到它的值,證明它的作用域是全域性的,而不是僅限於函數內部。

要想變數的作用域僅限於函數內部,可以在定義時加上local命令,此時該變數就成了區域性變數。請看下面的程式碼:
#!/bin/bash

#定義函數
function func(){
    local a=99
}

#呼叫函數
func

#輸出函數內部的變數
echo $a
輸出結果為空,表明變數 a 在函數外部無效,是一個區域性變數。

Shell 變數的這個特性和 JavaScript 中的變數是類似的。在 JavaScript 函數內部定義的變數,預設也是全域性變數,只有加上var關鍵字,它才會變成區域性變數。

本節只是演示了函數的定義和呼叫,並沒有對語法細節作過多說明,後續我們將在《Shell函數》一節中進行深入講解。

Shell 全域性變數

所謂全域性變數,就是指變數在當前的整個 Shell 進程中都有效。每個 Shell 進程都有自己的作用域,彼此之間互不影響。在 Shell 中定義的變數,預設就是全域性變數。

想要實際演示全域性變數在不同 Shell 進程中的互不相關性,可在圖形介面下同時開啟兩個 Shell,或使用兩個終端遠端連線到伺服器(SSH)。

首先開啟一個 Shell 視窗,定義一個變數 a 並賦值為 99,然後列印,這時在同一個 Shell 視窗中是可正確列印變數 a 的值的。然後再開啟一個新的 Shell 視窗,同樣列印變數 a 的值,但結果卻為空,如圖 1 所示。

打開兩個Shell窗口
圖1:開啟兩個 Shell 視窗