概述:shell變量的作用域,就是shell變量的有效范圍,在不同的作用域中,同名的變量不會相互干涉,就比如:A班級中有個叫小明的同學,B班級中也有一個叫小明的同學,由于他們不在同一個班級中,所以當在班級中叫到小明的名字的時候,不會造成混亂。
shell變量的作用域分為3種:
- 局部變量(local variable):只能在函數內部使用,需要使用local命令(局部變量只能在函數內部使用,但在函數內使用的變量不全是局部變量)
- 全局變量(global varlable):在當前的shell 進程中使用的變量,叫做全局變量
- 環(huán)境變量(environment variable):可以在子進程中使用。
1. shell 局部變量
在shell函數中定義的變量默認也為全局變量,需要使用local命令來聲明局部變量,觀查下面兩段代碼演示說明:
[root@docker /variable]# vim function_1.sh
#!/bin/bash
#定義函數
function fun(){
a=100
}
#調用函數
fun
#輸出函數內的變量值
echo $a
"function.sh" 12L, 69C 已寫入
[root@docker /variable]# sh function_1.sh
100
看輸出結果,變量a是在函數內部定義,但是在函數外部也可以得到變量a的值,證明它是一個全局變量。
[root@docker /variable]# vim function_2.sh
#!/bin/bash
#定義函數
function fun(){
local a=50
}
fun
echo $a
"function_2.sh" 12L, 77C 已寫入
[root@docker /variable]# sh function_2.sh
[root@docker /variable]#
輸出結果為空,說明變量a在函數外部無效,是一個局部變量,仔細看上面的腳本,使用local用來聲明局部變量。
2. shell 全局變量
所謂全局變量,就是指變量在當前shell進程中都有效,每個shell進程都有自己的作用域,彼此之間互不影響,在shell腳本中定義的變量,默認就是全局變量.
打開2個shell窗口,在其中一個窗口定義一個變量a并賦值100,然后打印a的值,發(fā)現輸出100;在另一個shell窗口同樣打印a的值,發(fā)現輸出結構為空。這說明全局變量a僅僅在定義它的shell進程中有效,對新的shell進程無效。如圖所示

**需要強調的是,全局變量的作用范圍是當前的進程,打開一個 Shell 窗口就創(chuàng)建了一個 Shell 進程,每個 Shell 進程都是獨立的,擁有不同的進程 ID,執(zhí)行shell腳本時也會生成一個進程,也會有用一個進程ID,所以想要使全局變量在這些腳本文件中都有效需要使用source 命令或. ./a.sh 的方法(source a.sh 命令表示在當前進程執(zhí)行shell腳本,和使用. ./a.sh 、. a.sh 效果相同) 演示如下: **
[root@docker /variable]# a=100
[root@docker /variable]# cat a.sh
#!/bin/bash
echo $a
b=200
[root@docker /variable]# cat b.sh
#!/bin/bash
echo $b
[root@docker /variable]# source a.sh
100
[root@docker /variable]# source b.sh
200
[root@docker /variable]#
3. shell 環(huán)境變量
全局變量旨在當前的shll進程中有效,對其他的進程和子進程都無效,如果使用==export==命令將全局變量導出,那么他就在所有子進程中都有效了,這稱之為“環(huán)境變量”。
環(huán)境變量被創(chuàng)建時所處的進程稱為父進程,如果在父進程中在創(chuàng)建一個細膩的進程來執(zhí)行shell命令,那么這個新的進程被稱作shell子進程,當shell子進程產生式,它會繼承父進程的環(huán)境變量為自己所用,所以說環(huán)境變量可從父進程傳給子進程,不難理解,環(huán)境變量還可以傳遞給孫進程。
創(chuàng)建shell子進程最簡單的方式就是運行bash命令(如圖所示)

[root@docker ~]$ a=22 #定義一個全局變量
[root@docker ~]$ echo $a #在當前Shell中輸出a,成功
22
[root@docker ~]$ bash #進入Shell子進程
[root@docker ~]$ echo $a #在子進程中輸出a,失敗
[root@docker ~]$ exit #退出Shell子進程,返回上一級Shell
exit
[root@docker ~]$ export a #將a導出為環(huán)境變量
[root@docker ~]$ bash #重新進入Shell子進程
[root@docker ~]$ echo $a #在子進程中再次輸出a,成功
22
[root@docker ~]$ exit #退出Shell子進程
exit
[root@docker ~]$ exit #退出父進程,結束整個Shell會話
可以發(fā)現,默認情況下,a 在 Shell 子進程中是無效的;使用 export 將 a 導出為環(huán)境變量后,在子進程中就可以使用了。
我們一直強調的是環(huán)境變量在 Shell 子進程中有效,并沒有說它在所有的 Shell 進程中都有效;如果你通過終端創(chuàng)建了一個新的 Shell 窗口,那它就不是當前 Shell 的子進程,環(huán)境變量對這個新的 Shell 進程仍然是無效的。
環(huán)境變量也是臨時的
通過 export 導出的環(huán)境變量只對當前 Shell 進程以及所有的子進程有效,如果最頂層的父進程被關閉了,那么環(huán)境變量也就隨之消失了,其它的進程也就無法使用了,所以說環(huán)境變量也是臨時的。
4. shell 配置文件(腳本)加載
無論是否是交互式、是否是登錄式,Bash shell 在啟動時總要配置其運行環(huán)境,例如初始化環(huán)境變量、設置命令提示符、指定系統(tǒng)命令路徑等。這過程都是通過加載一系列的配置文件完成的,這些配置文件其實就是腳本文件。
Bash 官方文檔說:如果是登錄式的 Shell,首先會讀取和執(zhí)行 /etc/profile,這是所有用戶的全局配置文件,接著會到用戶主目錄中尋找 /.bash_profile、/.bash_login 或者 ~/.profile,它們都是用戶個人的配置文件。
Bash shell 有關的配置文件主要有 /etc/profile、/.bash_profile、/.bash_login、/.profile、/.bashrc、/etc/bashrc、/etc/profile.d/*.sh,不同的啟動方式會加載不同的配置文件。
全局配置
/etc/profile此文件為系統(tǒng)的每個用戶設置環(huán)境信息,當用戶第一次登錄時,該文件被執(zhí)行。并從 /etc/profile.d 目錄的配置文件中收集 shell 的設置。如果你有對 /etc/profile 有修改的話必須得 source 一下你的修改才會生效,此修改對每個用戶都生效。
/etc/bashrc為每一個運行 bash shell 的用戶執(zhí)行此文件。當 bash shell 被打開時,該文件被讀取。如果你想對所有的使用 bash 的用戶修改某個配置并在以后打開的 bash 都生效的話可以修改這個文件,修改這個文件不用重啟,重新打開一個 bash 即可生效。
用戶配置
~/.bash_profile每個用戶都可使用該文件輸入專用于自己使用的 shell 信息,當用戶登錄時,該文件僅僅執(zhí)行一次!默認情況下,它設置一些環(huán)境變量,執(zhí)行用戶的~/ .bashrc 文件。 此文件類似于 /etc/profile,也是需要需要 source 才會生效,/etc/profile 對所有用戶生效,~/.bash_profile 只對當前用戶生效。
~/.profile(由Bourne Shell和Korn Shell使用)和.login(由C Shell使用)兩個文件是.bash_profile的同義詞,==目的是為了兼容其它Shell==。
如下.bash_profile系統(tǒng)默認配置:
[root@docker ~]# cat ~/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
[root@docker ~]#
~/.bashrc該文件包含專用于你的 bash shell 的 bash 信息,當登錄時以及每次打開新的 shell 時,該文件被讀取。(每個用戶都有一個 ~/.bashrc 文件,在用戶目錄下) 此文件類似于 /etc/bashrc,不需要重啟就可以生效,重新打開一個 bash 即可生效,/etc/bashrc 對所有用戶新打開的 bash 都生效,但 ~/.bashrc 只對當前用戶新打開的 bash 生效。
~/.bashrc文件會在bash shell調用另一個bash shell時讀取,也就是在shell中再鍵入bash命令啟動一個新shell時就會去讀該文件。這樣可有效分離登錄和子shell所需的環(huán)境。但一般 來說都會在/.bash_profile里調用/.bashrc腳本以便統(tǒng)一配置用戶環(huán)境。
5. 登錄式shell和非登錄式shell區(qū)別
-
登錄式shell
交互式登錄:(清除掉所有變量,通過文件重新讀入)
1.直接通過終端輸入賬號密碼登錄
2.使用“su - username”切換的用戶
執(zhí)行順序:(影響該shell的配置文件)/etc/profile --> /etc/profile.d/.sh --> ~/.bash_profile–> ~/.bashrc–> /etc/bashrc
-
非登錄式shell
如果以非登錄的方式啟動 Shell,那么就不會讀取以上所說的配置文件,而是直接讀取 ~/.bashrc;~/.bashrc 文件還會嵌套加載 /etc/bashrc。
1.su username
2.圖形界面下打開的終端
3.執(zhí)行腳本 (當我們執(zhí)行腳本的時候.我們就已經進入到了一個子shell)
4.任何其它的bash實例
執(zhí)行順序:(影響該shell的配置文件)~/.bashrc–> /etc/bashrc–> /etc/profile.d/.sh
6.檢查系統(tǒng)環(huán)境變量的命令
- set 輸出所有變量,包括全局變量、局部變量
- env 只顯示痊愈變量
- declare 輸出所有的變量,如同 set
- export 只顯示和設置環(huán)境變量值
7.刪除環(huán)境變量
- unset 變量名 ,刪除變量或函數。