什么是環(huán)境變量
環(huán)境變量是描述系統(tǒng)運行環(huán)境的一系列變量,如PATH描述了應該去哪里查找命令,SHELL描述了默認的shell是哪個。
加載環(huán)境變量
當一個shell啟動時會從某個文件讀入環(huán)境變量,例如bash的環(huán)境變量就和~/.bashrc 文件密切相關。
普通變量
書上把shell里面的變量分為全局和局部,站在環(huán)境變量的角度,以我的理解我把shell里面的變量分為兩種,普通變量和環(huán)境變量
我們在bash里面定義一個變量newvar看看它是否和環(huán)境變量性質(zhì)一樣
$set newvar 8
$echo $newvar
8
定義變量之后,使用env這個命令查看環(huán)境變量,發(fā)現(xiàn)自己定義的變量并不包含在里面。這說明自己定義的變量和環(huán)境變量并不是一樣的,他們是兩種不同的變量。
兩種變量的比較
- 兩種變量都可以被set和unset,即被創(chuàng)建和刪除
比如,我們嘗試unset掉HOME這個環(huán)境變量
$echo $HOME
/home/user
$unset $HOME
$echo $HOME
我們發(fā)現(xiàn)HOME這個環(huán)境變量已經(jīng)成功地被unset了。但是如果你此時另開一個shell你會發(fā)現(xiàn)這個HOME又回來了,這不難理解,因為shell每次啟動都是從文件加載環(huán)境變量,而unset操作只是把導入shell里面的變量刪除掉,而不會對導入環(huán)境變量的文件進行操作。
-
從屬關系
環(huán)境變量屬于當前shell及其子進程
比如你可以在
~/.bashrc文件里自己加上一個變量myvar=9,那么bash啟動時myvar就被加載成了環(huán)境變量,然后在bash里面再開一個bash,你會發(fā)現(xiàn)你放進文件里的myvar也會在子shell進程里。但是這里有個問題,你怎么知道子進程里的myvar是從它的父進程shell來的還是從文件來的?這個問題后文變量轉(zhuǎn)換的時候可以解決。
普通變量只屬于當前shell進程
普通變量不會出現(xiàn)在子shell進程中,如果想要它存在與子shell進程,需要將其轉(zhuǎn)換成環(huán)境變量。
相關操作
env
env //顯示當前環(huán)境變量
env -i NAME=value COMMAND
env -u NAME COMMAND
-i 參數(shù)表示不帶環(huán)境變量啟動,COMMAND是命令,可以是腳本或程序等
-u 參數(shù)表示從環(huán)境變量里面刪除一個變量,然后運行COMMAND
更多命令去問男人吧man env
Talk is cheap. Show me the code!
user@myzone ~>env //顯示全部,內(nèi)容太多,略去
user@myzone ~>set a 5
user@myzone ~>echo $a
5
user@myzone ~>env -i PATH=mypath echo.sh
mypath
user@myzone ~>export a //將a設置為環(huán)境變量,詳見下文
user@myzone ~>fish //這是子shell進程
user@myzone ~>echo $a
5
user@myzone ~>env -u a fish //子shell進程里面又開了一個shell進程
user@myzone ~>echo $a
user@myzone ~>exit
user@myzone ~>exit
echo.sh是自己寫的一個腳本,功能是顯示PATH的值
#!/bin/sh
echo $PATH
可以看到運行echo.sh 時PATH已被env修改
a是子shell里面的環(huán)境變量,env 加-u之后將其刪除,所以在孫子shell(姑且這么說吧哈哈)就不存在a這個變量了
export
將一個變量a變成環(huán)境變量,但是只對子進程起作用,子進程中的a和PATH等環(huán)境變量無差別即如果再有子進程,a也是會被傳遞到子進程的,記住上文說的只有兩種變量。有了這個命令我們就可以解釋上文從屬關系里面的問題了
user@myzone ~>set val 3
user@myzone ~>export val //轉(zhuǎn)換成環(huán)境變量
user@myzone ~>fish //子shell進程
user@myzone ~>echo $val
3
由于export將val轉(zhuǎn)換成了環(huán)境變量,子shell里面也有這個val,而文件里面沒有val這個變量,因此子shell里的val是從調(diào)用它的那個shell來的
set/unset/echo
三個命令都比較簡單,且看名字就知道是干嘛的,不詳細敘述了。需要注意的是,不同的shell命令可能會不同,如fish沒有unset 而有set -e 也沒有NAME=VALUE 這種定義變量的寫法,而只能set NAME VALUE ,具體區(qū)別,RTFM吧!