Linux shell 学习笔记(4)— linux 环境变量(全局变量、局部变量及变量持久化)
1. 環境變量概念及分類
bash shell 用一個叫作環境變量(environment variable)的特性來存儲有關 shell 會話和工作環境的信息(這也是它們被稱作環境變量的原因)。這項特性允許你在內存中存儲數據,以便程序或shell 中運行的腳本能夠輕松訪問到它們。
在bash shell中,環境變量分為兩類:
- 全局變量
- 局部變量
1.1 全局環境變量
全局環境變量對于 shell 會話和所有生成的子 shell 都是可見的。局部變量則只對創建它們的 shell可見。Linux 系統在你開始 bash 會話時就設置了一些全局環境變量,系統環境變量基本上都是使用全大寫字母,以區別于普通用戶的環境變量。
要查看全局變量,可以使用 env 或 printenv 命令:
$ printenv
HOSTNAME=server01.class.edu
SELINUX_ROLE_REQUESTED=
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
[...]
HOME=/home/Christine
LOGNAME=Christine
[...]
G_BROKEN_FILENAMES=1
_=/usr/bin/printenv
要顯示個別環境變量的值,可以使用 printenv 命令,但是不要用 env 命令。
$ printenv HOME
/home/Christine
$
$ env HOME
env: HOME: No such file or directory
$
也可以使用 echo 顯示變量的值。在這種情況下引用某個環境變量的時候,必須在變量前面加上一個美元符($)。
$ echo $HOME
/home/Christine
$
1.2 局部環境變量
局部環境變量只能在定義它們的進程中可見,事實上,Linux 系統也默認定義了標準的局部環境變量。不過你也可以定義自己的局部變量,如你所想,這些變量被稱為用戶定義局部變量。
set 命令會顯示為某個特定進程設置的所有環境變量,包括局部變量、全局變量以及用戶定義變量。
$ set
BASH=/bin/bash
[...]
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
[...]
colors=/etc/DIR_COLORS
my_variable='Hello World'
[...]
$
注意:命令 env、printenv 和 set 之間的差異很細微。set 命令會顯示出全局變量、局部變量以及用戶定義變量。它還會按照字母順序對結果進行排序。env 和 printenv 命令同 set 命令的區別在于前兩個命令不會對變量排序,也不會輸出局部變量和用戶定義變量。
2. 設置自定義變量
2.1 設置局部用戶自定義變量
一旦啟動了 bash shell(或者執行一個 shell 腳本),就能創建在這個 shell 進程內可見的局部變量了。可以通過等號給環境變量賦值,值可以是數值或字符串。
$ echo $my_variable
$ my_variable=Hello
$
$ echo $my_variable
Hello
如果要給變量賦一個含有空格的字符串值,必須用單引號來界定字符串的首和尾。
$ my_variable=Hello World
-bash: World: command not found
$
$ my_variable="Hello World"
$
$ echo $my_variable
Hello World
$
你定義的局部環境變量用的是小寫字母,而到目前為止你所看到的系統環境變量都是大寫字母。
注意:所有的環境變量名均使用大寫字母,這是 bash shell 的標準慣例。如果是你自己創建的局部變量或是 shell 腳本,請使用小寫字母。變量名區分大小寫。在涉及用戶定義的局部變量時堅持使用小寫字母,這能夠避免重新定義系統環境變量可能帶來的災難。
記住,變量名、等號和值之間沒有空格,這一點非常重要。如果在賦值表達式中加上了空格,bash shell 就會把值當成一個單獨的命令:
$ my_variable = "Hello World"
-bash: my_variable: command not found
$
設置了局部環境變量后,就能在 shell 進程的任何地方使用它了。但是,如果生成了另外一個shell,它在子 shell 中就不可用。
$ my_variable="Hello World"
$
$ bash
$
$ echo $my_variable
$ exit
exit
$
$ echo $my_variable
Hello World
$
在這個例子中生成了一個子 shell。在子 shell 中無法使用用戶定義變量 my_variable。通過命令echo $my_variable 所返回的空行就能夠證明這一點。當你退出子 shell 并回到原來的 shell 時,這個局部環境變量依然可用。
類似地,如果你在子進程中設置了一個局部變量,那么一旦你退出了子進程,那個局部環境變量就不可用。
2.2 設置全局環境變量
在設定全局環境變量的進程所創建的子進程中,該變量都是可見的。創建全局環境變量的方法是先創建一個局部環境變量,然后再把它導出到全局環境中。
-
這個過程通過export命令來完成,變量名前面不需要加$。
$ my_variable="I am Global now" $ $ export my_variable $ $ echo $my_variable I am Global now $ $ bash $ $ echo $my_variable I am Global now $ $ exit exit $ $ echo $my_variable I am Global now $?
-
修改子shell中全局環境變量并不會影響到父shell中該變量的值。
$ my_variable="I am Global now" $ export my_variable $ $ echo $my_variable I am Global now $ $ bash $ $ echo $my_variable I am Global now $ $ my_variable="Null" $ $ echo $my_variable Null $ $ exit exit $ $ echo $my_variable I am Global now $?
-
子shell甚至無法使用export命令改變父shell中全局環境變量的值。
$ my_variable="I am Global now" $ export my_variable $ $ echo $my_variable I am Global now $ $ bash $ $ echo $my_variable I am Global now $ $ my_variable="Null" $ $ export my_variable $ $ echo $my_variable Null $ $ exit exit $ $ echo $my_variable I am Global now $
3. 刪除環境變量
既然可以創建新的環境變量,自然也能刪除已經存在的環境變量。可以用 unset 命令完成這個操作。在 unset 命令中引用環境變量時,記住不要使用 $。
$ echo $my_variable
I am Global now
$
$ unset my_variable
$
$ echo $my_variable
$
#在涉及環境變量名時,什么時候該使用 $,什么時候不該使用 $,實在讓人摸不著頭腦。
#記住一點就行了:如果要用到變量,使用 $;如果要操作變量,不使用 $。這條規則的一
#個例外就是使用 printenv 顯示某個變量的值。
在處理全局環境變量時,事情就有點棘手了。如果你是在子進程中刪除了一個全局環境變量,這只對子進程有效。該全局環境變量在父進程中依然可用。
$ my_variable="I am Global now"
$
$ export my_variable
$
$ echo $my_variable
I am Global now
$
$ bash
$
$ echo $my_variable
I am Global now
$
$ unset my_variable
$
$ echo $my_variable
$ exit
exit
$
$ echo $my_variable
I am Global now
$
和修改變量一樣,在子 shell 中刪除全局變量后,你無法將效果反映到父 shell 中。
4. 設置 PATH 環境變量
當你在 shell 命令行界面中輸入一個外部命令時,shell 必須搜索系統來找到對應的程序。PATH 環境變量定義了用于進行命令和程序查找的目錄。
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:
/sbin:/bin:/usr/games:/usr/local/games
$
輸出中顯示了有 8 個可供 shell 用來查找命令和程序。PATH 中的目錄使用冒號分隔。
如果命令或者程序的位置沒有包括在 PATH 變量中,那么如果不使用絕對路徑的話,shell 是沒法找到的。如果 shell 找不到指定的命令或程序,它會產生一個錯誤信息:
$ myprog
-bash: myprog: command not found
$
問題是,應用程序放置可執行文件的目錄常常不在 PATH 環境變量所包含的目錄中。解決的辦法是保證 PATH 環境變量包含了所有存放應用程序的目錄。
可以把新的搜索目錄添加到現有的 PATH 環境變量中,無需從頭定義。PATH 中各個目錄之間是用冒號分隔的。你只需引用原來的 PATH 值,然后再給這個字符串添加新目錄就行了。可以參考下面的例子。
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:
/sbin:/bin:/usr/games:/usr/local/games
$
$ PATH=$PATH:/home/christine/Scripts
$
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/
games:/usr/local/games:/home/christine/Scripts
$
$ myprog
The factorial of 5 is 120.
$
對 PATH 變量的修改只能持續到退出或重啟系統。這種效果并不能一直持續。
5. 環境變量持久化
對全局環境變量來說(Linux系統中所有用戶都需要使用的變量),可能更傾向于將新的或修改過的變量設置放在 /etc/profile 文件中,但這可不是什么好主意。如果你升級了所用的發行版,這個文件也會跟著更新,那你所有定制過的變量設置可就都沒有了。
最好是在 /etc/profile.d目錄中創建一個以.sh 結尾的文件。把所有新的或修改過的全局環境變量設置放在這個文件中。
在大多數發行版中,存儲個人用戶永久性 bash shell 變量的地方是 $HOME/.bashrc 文件。這一點適用于所有類型的 shell 進程。但如果設置了 BASH_ENV變量,那么記住,除非它指向的是
$HOME/.bashrc,否則你應該將非交互式 shell 的用戶變量放在別的地方。
6. 數組變量
環境變量有一個很酷的特性就是,它們可作為數組使用。
-
要給某個環境變量設置多個值,可以把值放在括號里,值與值之間用空格分隔
$ mytest=(one two three four five) $ -
要引用一個單獨的數組元素,就必須用代表它在數組中位置的數值索引值。索引值要用方括號括起來
$ echo ${mytest[2]} three $ -
要顯示整個數組變量,可用星號作為通配符放在索引值的位置
$ echo ${mytest[*]} one two three four five $ -
也可以改變某個索引值位置的值
$ mytest[2]=seven $ $ echo ${mytest[*]} one two seven four five $ -
甚至能用 unset 命令刪除數組中的某個值,但是要小心,這可能會有點復雜
$ unset mytest[2] $ $ echo ${mytest[*]} one two four five $ $ echo ${mytest[2]} $ echo ${mytest[3]} four $這個例子用 unset 命令刪除在索引值為 2 的位置上的值。顯示整個數組時,看起來像是索引里面已經沒這個索引了。但當專門顯示索引值為 2 的位置上的值時,就能看到這個位置是空的。
-
可以在 unset 命令后跟上數組名來刪除整個數組
$ unset mytest $ $ echo ${mytest[*]} $
總結
以上是生活随笔為你收集整理的Linux shell 学习笔记(4)— linux 环境变量(全局变量、局部变量及变量持久化)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux shell 学习笔记(3)—
- 下一篇: Linux shell 学习笔记(5)—