Shell 全局變量、環境變量和局部變量

Shell 變量的做用域(Scope),就是 Shell 變量的有效範圍(可使用的範圍)。

在不一樣的做用域中,同名的變量不會相互干涉,就好像 A 班有個叫小明的同窗,B 班也有個叫小明的同窗,雖然他們都叫小明(對應於變量名),可是因爲所在的班級(對應於做用域)不一樣,因此不會形成混亂。可是若是同一個班級中有兩個叫小明的同窗,就必須用相似於「大小明」、「小小明」這樣的命名來區分他們。

Shell 變量的做用域能夠分爲三種:java

  • 有的變量能夠在當前 Shell 會話中使用,這叫作全局變量(global variable);
  • 有的變量只能在函數內部使用,這叫作局部變量(local variable);
  • 而有的變量還能夠在其它 Shell 中使用,這叫作環境變量(environment variable)。

全局變量

所謂全局變量,就是指變量在當前的整個 Shell 會話中都有效。每一個 Shell 會話都有本身的做用域,彼此之間互不影響。在 Shell 中定義的變量,默認就是全局變量。

想要實際演示全局變量在不一樣 Shell 會話中的互不相關性,可在圖形界面下同時打開兩個 Shell,或使用兩個終端遠程鏈接到服務器(SSH)。

首先打開一個 Shell 窗口,定義一個變量 a 並賦值爲 1,而後打印,這時在同一個 Shell 窗口中是可正確打印變量 a 的值的。而後再打開一個新的 Shell 窗口,一樣打印變量 a 的值,但結果卻爲空,如圖 1 所示。
 shell

打開兩個Shell會話
圖1:打開兩個 Shell 會話編程


這說明全局變量 a 僅僅在定義它的第一個 Shell 中有效,對其它 Shell 沒有影響。這很好理解,就像小王家和小徐家都有一部電視機(變量名相同),可是同一時刻小王家和小徐家的電視中播放的節目能夠是不一樣的(變量值不一樣)。

須要強調的是,全局變量的做用範圍是當前的 Shell 會話,而不是當前的 Shell 腳本文件,它們是不一樣的概念。打開一個 Shell 窗口就建立了一個 Shell 會話,打開多個 Shell 窗口就建立了多個 Shell 會話,每一個 Shell 會話都是獨立的進程,擁有不一樣的進程 ID。在一個 Shell 會話中,能夠執行多個 Shell 腳本文件,此時全局變量在這些腳本文件中都有效。

例如,如今有兩個 Shell 腳本文件,分別是 a.sh 和 b.sh。a.sh 的代碼以下:bash

  1.  
     
  2.  
    #!/bin/bash
  3.  
    echo $a
  4.  
    b=200

b.sh 的代碼以下:服務器

  1.  
    #!/bin/bash
  2.  
    echo $b

打開一個 Shell 窗口,輸入如下命令:編程語言

  1.  
    $ a= 99
  2.  
    $ . ./a.sh
  3.  
    99
  4.  
    $ . b.sh
  5.  
    200
  6.  
    $

從輸出結果能夠發現,在 Shell 會話中以命令行的形式定義的變量 a,在 a.sh 中有效;在 a.sh 中定義的變量 b,在 b.sh 中也有效。函數

局部變量

Shell 也支持自定義函數,可是 Shell 函數和 C/C++Java 等其餘編程語言函數的一個不一樣點就是:在 Shell 函數中定義的變量默認也是全局變量,它和在函數外部定義變量擁有同樣的效果。請看下面的代碼:spa

  1.  
    #!/bin/bash
  2.  
     
  3.  
    #定義函數
  4.  
    function func(){
  5.  
    a=99
  6.  
    }
  7.  
     
  8.  
    #調用函數
  9.  
    func
  10.  
     
  11.  
    #輸出函數內部的變量
  12.  
    echo $a

輸出結果:
99

a 是在函數內部定義的,可是在函數外部也能夠獲得它的值,證實它的做用域是全局的,而不是僅限於函數內部。

要想變量的做用域僅限於函數內部,那麼能夠在定義時加上local命令,此時該變量就成了局部變量。請看下面的代碼:.net

  1.  
     
  2.  
    #!/bin/bash
  3.  
     
  4.  
    #定義函數
  5.  
    function func(){
  6.  
    local a=99
  7.  
    }
  8.  
     
  9.  
    #調用函數
  10.  
    func
  11.  
     
  12.  
    #輸出函數內部的變量
  13.  
    echo $a

輸出結果爲空,代表變量 a 在函數外部無效,是一個局部變量。

Shell 變量的這個特性和 JavaScript 中的變量是相似的。在 JavaScript 函數內部定義的變量,默認也是全局變量,只有加上var關鍵字,它纔會變成局部變量。命令行

環境變量

全局變量只在當前 Shell 會話中有效,若是使用export命令將它導出,那麼它就在全部的子 Shell 中也有效了,這稱爲「環境變量」。

環境變量被建立時所處的 Shell 被稱爲父 Shell,若是在父 Shell 中再建立一個 Shell,則該 Shell 被稱做子 Shell。當子 Shell 產生時,它會繼承父 Shell 的環境變量爲本身所用,因此說環境變量可從父 Shell 傳給子 Shell。不難理解,環境變量還能夠傳遞給孫 Shell。

注意,環境變量只能向下傳遞而不能向上傳遞,即「傳子不傳父」。

在一個 Shell 中建立子 Shell 最簡單的方式是運行 bash 命令,如圖 2 所示。
 

進入子 Shell
圖2:進入子 Shell


經過exit命令能夠一層一層地退出 Shell。

下面演示一下環境變量的使用:

  1.  
    $ a=22      #定義一個全局變量
  2.  
    $ echo $a    #在當前Shell中輸出a,成功
  3.  
    22
  4.  
    $ bash    #進入子Shell
  5.  
    $ echo $a    #在子Shell中輸出a,失敗
  6.  
     
  7.  
    $ exit    #退出子Shell
  8.  
    exit
  9.  
    $ export a    #將a導出爲環境變量
  10.  
    $ bash    #從新進入子Shell
  11.  
    $ echo $a    #在子Shell中再次輸出a,成功
  12.  
    22
  13.  
    $ exit    #退出子Shell
  14.  
    exit
  15.  
    $ exit    #退出父Shell,結束整個Shell會話

能夠發現,默認狀況下,a 在子 Shell 中是無效的;使用 export 將 a 導出爲環境變量後,在子 Shell 中就可使用了。

export a這種形式是在定義變量 a 之後再將它導出爲環境變量,若是想在定義的同時導出爲環境變量,能夠寫做export a=22

注意,本節咱們一直強調的是環境變量在子 Shell 中有效,並無說它在全部的 Shell 種有效;若是你經過終端建立一個新的 Shell,那麼它就不是當前 Shell 的子 Shell,環境變量對這個 Shell 就是無效的。

此外,經過export命令導出的環境變量是臨時的,關閉 Shell 會話後它就銷燬了。因此,這種環境變量也只是在局部範圍內起做用,並不影響全部 Shell。若是想讓環境變量在全部 Shell 中都有效,而且可以永久保存,在關閉 Shell 後也不丟失,那麼就須要把環境變量寫入啓動文件。至於如何寫入文件,請你們自行百度,這裏就再也不贅述了。

相關文章
相關標籤/搜索