linux shell “永久環境變數”、“臨時環境變數”和"普通變數"之完全解讀

來源:互聯網
上載者:User

標籤:

        這個年代, 大家寫點書, 也無非就是為了搞點錢, 基本都是羅列一些知識點, 基本都是寫給已經會了的人看的。 真正用心寫書的人, 不多。 如果真正用心寫書, 且站在讀者的角度去寫, 那就少之又少了。


        關於linux shell環境變數, 我看了四本linux相關書的介紹, 結果, 沒有一本書的講解讓我完全滿意, 總感覺沒有說清楚。所以呢, 我打算自己來寫一下,如有不當指出, 請大家指正。



        一. 永久環境變數(實際上屬於檔案, 而不屬於shell, 每開啟一個shell, 都會載入/匯入到shell中, 形成當前shell的臨時環境變數)

        先說說"永久環境變數", 其實, 我也知道, 沒有什麼東西是真正永久的, 這裡的永久是指: 變數儲存在檔案中, 不會因為掉電或者關機而消失。下面, 我們開啟一個linux shell, 並列印HOME的值, 如下:

 [[email protected] Desktop]$ echo $HOME
/home/taoge 

       我們看到HOME這個變數的值是/home/taoge, 這個變數的值是從哪裡來的呢? 我們可以看看使用者主目錄下的.bashrc檔案

 [[email protected] Desktop]$ cat ~/.bashrc 

      其中的內容為:

# .bashrc# Source global definitionsif [ -f /etc/bashrc ]; then        . /etc/bashrcfi# User specific aliases and functions

       啊? 居然沒有HOME? 不要著急, 先姑且認為是在/etc/bashrc中進行了HOME的設定吧, 在此, 我們不深究, 只需要有這個認識: HOME與檔案~/.bashrc密切相關, 即使斷電或者掉電, 也不怕消失。


      實際上, 當我們開啟一個shell進程的時候, HOME這個永久環境變數會自動匯入到當前的shell中來(為當前shell設定了一個臨時的環境變數), 那這個HOME可不可以被unset掉呢? 我們來看一下:

[[email protected] Desktop]$ echo $HOME
/home/taoge
[[email protected] Desktop]$ unset HOME
[[email protected] Desktop]$ echo $HOME


[[email protected] Desktop]$ 

      我們看到, 當前shell進程中的HOME確實是被unset掉了, 不要著急, 我們另外開啟一個shell進程, 然後看看有沒有HOME,  如下:

[[email protected] Desktop]$ echo $HOME
/home/taoge
[[email protected] Desktop]$  
      可以看到, 第二個shell進程中是有HOME的, 這個不難理解, 因為開啟第二個shell進程的時候, 會把~/.bashrc中的永久HOME載入一次, 所以可以看到/home/taoge.


      我們暫時來總結一下: 永久環境變數存在於~/.bashrc檔案中(掉電或者重啟後, 不會消失), 在每個shell啟動的時候, 都會將永久環境變數匯入到shell中, 並成為shell的臨時環境變數, 這個臨時的環境變數可以被unset掉後, 但不會影響其他shell, 因為我們即將會說到, 不同shell的臨時環境變數是彼此獨立的。


      下面,你可能還在糾結並不耐煩地發出疑問:在~/.bashrc中沒有看到HOME啊, 你不是在扯淡嗎? 好, 我們自己來把一個變數寫入到~/.bashrc檔案中, 使之成為永久環境變數, ~/.bashrc檔案內容如下:

# .bashrc# Source global definitionsif [ -f /etc/bashrc ]; then        . /etc/bashrcfi# User specific aliases and functions# define permanent variable by taogewinner="people who persists"

      我定義winner這個變數的值為“people who persists”, 好, 儲存檔案, 我們來查看一下winner這個變數, 如下:

[[email protected] Desktop]$ echo $winner

[[email protected] Desktop]$  

      遺憾的是, 我們沒有看到winner, 為什麼呢? 因為現在只是把winner變成了永久環境變數, 這個永久環境變數並沒有載入到當前的shell中來啊! 好吧, 我們關掉當前的shell, 並開啟一個新的shell,  再查看一次, 如下:

[[email protected] Desktop]$ echo $winner
people who persists
[[email protected] Desktop]$  

      可以看到, 這次winner有值了, 激動吧。 這樣, 無論以後是重啟linux, 還是怎麼滴, winner就成為了檔案的一部分, 就成了永久的環境變數了。 當然, 你要是把~/.bashrc檔案中的winner那一行刪除了, 然後跟我說:你不是說永久的嗎? 現在怎麼不永久啦?  好吧, 你這是在故意找茬。




      二. 臨時的環境變數(屬於當前shell及其子進程)

       上面我們已經說了, winner成了永久的環境變數, 當一個shell開啟的時候, 便會載入這個winner變數, 那麼在當前shell環境中, 這個winner就會變成臨時的環境變數。 之所以說是臨時的, 是因為你可以把他unset掉, 之所以說是環境變數, 意思是說(沒被unset掉的時候), 當前shell進程的子進程可以訪問到該winner, 如下:

[[email protected] Desktop]$ echo $$
7203
[[email protected] Desktop]$ echo $winner
people who persists
[[email protected] Desktop]$ bash
[[email protected] Desktop]$ echo $$
7354
[[email protected] Desktop]$ echo $winner
people who persists
[[email protected] Desktop]$ exit
exit
[[email protected] Desktop]$ echo $$
7203
[[email protected] Desktop]$ 

      我們看到, 當前進程pid是7203, 為它再開一個子shell進程, 子進程的pid為7354, 我們可以看到, 在進程中, 也可以訪問到winner.   


      上面的winner是~/.bashrc中永久環境變數載入而來的, 那我們可不可以自訂臨時環境變數呢? 可以的。 這次, 我們運行a.sh指令碼來做當前shell的子進程, 如下:

[[email protected] Desktop]$ export x="defined in shell"
[[email protected] Desktop]$ vim a.sh
[[email protected] Desktop]$ cat a.sh 
#! /bin/bash
echo $x
[[email protected] Desktop]$ chmod +x a.sh 
[[email protected] Desktop]$ ./a.sh 
defined in shell
[[email protected] Desktop]$ 

     可以看到, 在指令碼子進程中, 也可以訪問x這個臨時的環境變數。 好, 我問個問題, 那別的shell能訪問這個x嗎?  我們再開啟另外一個shell, 如下:

[[email protected] Desktop]$ echo $x

[[email protected] Desktop]$     

     肯定是沒有啊, 上面的一些例子都揭露了臨時環境變數的本質: 當前shell的臨時環境變數, 能被自己及其子進程(子shell進程, 子指令碼進程或者子C程式進程)訪問, 但不能被其它shell訪問(相互獨立)。 對了, 我們上面已經討論過了, 臨時的環境變數可以被unset掉。在實際大型的軟體開發中, 編譯大工程, 經常需要用到臨時環境變數。




      三. 普通變數(屬於當前shell進程)

      shell中的普通變數很簡單, 僅能被當前shell訪問, 不能被其子進程訪問, 更不能被其它shell訪問。 當然, 它也可以被unset掉, 測試如下:

[[email protected] Desktop]$ z="f(y)"
[[email protected] Desktop]$ echo $z
f(y)
[[email protected] Desktop]$ echo $$
7578
[[email protected] Desktop]$ bash
[[email protected] Desktop]$ echo $$
7653
[[email protected] Desktop]$ echo $z

[[email protected] Desktop]$ exit
exit
[[email protected] Desktop]$ echo $$
7578
[[email protected] Desktop]$ unset z
[[email protected] Desktop]$ echo $z

[[email protected] Desktop]$ 

     可見, 確實不能被子shell訪問, 當然, 肯定更不能被其它shell訪問了。   普通變數要提升了臨時的環境變數, 那也很簡單, 加一下export就可以了, 如下:
 [[email protected] Desktop]$ z="f(y)"
[[email protected] Desktop]$ echo $z
f(y)
[[email protected] Desktop]$ echo $$
7578
[[email protected] Desktop]$ export z
[[email protected] Desktop]$ bash
[[email protected] Desktop]$ echo $$
7723
[[email protected] Desktop]$ echo $z
f(y)
[[email protected] Desktop]$ exit
exit
[[email protected] Desktop]$ echo $$
7578
[[email protected] Desktop]$ 


       囉嗦地總結一下: shell中的普通變數, 僅能被當前shell訪問, 不能被其子進程訪問, 更不能被其它shell訪問。 當然, 它也可以被unset掉。



      OK,  我覺得我應該說清楚了, 早休息!








     

linux shell “永久環境變數”、“臨時環境變數”和"普通變數"之完全解讀

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.