一、環(huán)境變量
1.變量
要解釋環(huán)境變量蕊玷,得先明白變量是什么心赶,準(zhǔn)確的說應(yīng)該是 Shell 變量扣讼,所謂變量就是計算機(jī)中用于記錄一個值(不一定是數(shù)值,也可以是字符或字符串)的符號缨叫,而這些符號將用于不同的運算處理中椭符。
通常變量與值是一對一的關(guān)系,可以通過表達(dá)式讀取它的值賦值給其它變量耻姥,也可以直接指定數(shù)值賦值給任意變量销钝。為了便于運算和處理,大部分的編程語言會區(qū)分變量的類型琐簇,用于分別記錄數(shù)值蒸健、字符或者字符串等等數(shù)據(jù)類型。Shell 中的變量也基本如此,有不同類型(但不用專門指定類型名)似忧,可以參與運算渣叛,有作用域限定。
變量的作用域即變量的有效范圍(比如一個函數(shù)中盯捌、一個源文件中或者全局范圍)淳衙,在該范圍內(nèi)只能有一個同名變量。一旦離開則該變量無效饺著,如同不存在這個變量一般箫攀。
在 Shell 中如何創(chuàng)建一個變量,如何給變量賦值和如何讀取變量的值呢瓶籽?這部分內(nèi)容會在bash 腳本編程這門課中詳細(xì)介紹匠童,這里我簡單舉例說明一下:
使用declare命令創(chuàng)建一個變量名為 tmp 的變量:$ declare tmp
其實也可以不用 declare 預(yù)聲明一個變量埂材,直接即用即創(chuàng)建塑顺,這里只是告訴你 declare 的作用,這在創(chuàng)建其它指定類型的變量(如數(shù)組)時會用到俏险。
使用=號賦值運算符為變量 tmp 賦值為 shiyanlou:$ tmp=shiyanlou
讀取變量的值严拒,使用echo命令和$符號($符號用于表示引用一個變量的值,初學(xué)者經(jīng)常會忘記輸入):
$ echo $tmp
![](https://dn-anything-about-doc.qbox.me/linux_base/5-1.png/logoblackfont)
注意:關(guān)于變量名竖独,并不是任何形式的變量名都是可用的裤唠,變量名只能是英文字母,數(shù)字或者下劃線,且不能以數(shù)字作為開頭莹痢。
2.環(huán)境變量
簡單理解了變量的概念种蘸,就很好解釋環(huán)境變量了,環(huán)境變量就是作用域比自定義變量要大竞膳,如Shell 的環(huán)境變量作用于自身和它的子進(jìn)程航瞭。在所有的 UNIX 和類 UNIX 系統(tǒng)中,每個進(jìn)程都有其各自的環(huán)境變量設(shè)置坦辟,且默認(rèn)情況下刊侯,當(dāng)一個進(jìn)程被創(chuàng)建時,處理創(chuàng)建過程中明確指定的話锉走,它將繼承其父進(jìn)程的絕大部分環(huán)境設(shè)置滨彻。Shell 程序也作為一個進(jìn)程運行在操作系統(tǒng)之上,而我們在 Shell中運行的大部分命令都將以 Shell 的子進(jìn)程的方式運行挪蹭。
![](https://dn-anything-about-doc.qbox.me/linux_base/5-2.png/logoblackfont)
通常我們會涉及到的環(huán)境變量有三種:
- 當(dāng)前 Shell 進(jìn)程私有用戶自定義變量亭饵,如上面我們創(chuàng)建的 temp 變量,只在當(dāng)前 Shell 中有效梁厉。
- Shell 本身內(nèi)建的變量冬骚。
- 從自定義變量導(dǎo)出的環(huán)境變量。
也有三個與上述三種環(huán)境變量相關(guān)的命令,set只冻,env庇麦,export。這三個命令很相似喜德,都可以用于打印相關(guān)環(huán)境變量,區(qū)別在于涉及的是不同范圍的環(huán)境變量山橄,
- set
顯示當(dāng)前 Shell 所有環(huán)境變量,包括其內(nèi)建環(huán)境變量(與 Shell 外觀等相關(guān))舍悯,用戶自定義變量及導(dǎo)出的環(huán)境變量
- env
顯示與當(dāng)前用戶相關(guān)的環(huán)境變量航棱,還可以讓命令在指定環(huán)境中運行
- export
顯示從 Shell 中導(dǎo)出成環(huán)境變量的變量,也能通過它將自定義變量導(dǎo)出為環(huán)境變量
![](https://dn-anything-about-doc.qbox.me/linux_base/5-3.png/logoblackfont)
你可以更直觀的使用vimdiff工具比較一下它們之間的差別:
$ temp=shiyanlou
$ export temp_env=shiyanlou
$ env|sort>env.txt
$ export|sort>export.txt
$ set|sort>set.txt
上述操作將命令輸出通過管道|使用sort命令排序萌衬,再重定向到對象文本文件中饮醇。
$ vimdiff env.txt export.txt set.txt
使用vimdiff工具比較導(dǎo)出的幾個文件的內(nèi)容。
![](https://dn-anything-about-doc.qbox.me/linux_base/5-4.png)
關(guān)于環(huán)境變量秕豫,可以簡單的理解成在當(dāng)前進(jìn)程的子進(jìn)程是否有效朴艰,有效則為環(huán)境變量,否則不是(有些人也將所有變量統(tǒng)稱為環(huán)境變量混移,只是以全局環(huán)境變量和局部環(huán)境變量進(jìn)行區(qū)分祠墅,我們只要理解它們的實質(zhì)區(qū)別即可)。我們這里用export命令來體會一下歌径,先在 Shell 中設(shè)置一個變量temp=shiyanlou毁嗦,然后再新創(chuàng)建一個子 Shell 查看temp
變量的值:
![](https://dn-anything-about-doc.qbox.me/linux_base/5-5.png/logoblackfont)
注意:為了與普通變量區(qū)分,通常我們習(xí)慣將環(huán)境變量名設(shè)為大寫
3.命令的查找路徑與順序
你可能很早之前就有疑問回铛,我們在 Shell 中輸入一個命令狗准,Shell 是怎么知道在哪去找到這個命令然后執(zhí)行的呢?這是通過環(huán)境變量PATH來進(jìn)行搜索的茵肃,熟悉 Windows 的用戶可能知道 Windows 中的也是有這么一個 PATH 環(huán)境變量.
這個PATH里面就保存了Shell中執(zhí)行的命令的搜索路徑腔长。
- 查看PATH環(huán)境變量的內(nèi)容:
$ echo $PATH
默認(rèn)情況下你會看到如下輸出:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
如果你還記得我們在 Linux 目錄結(jié)構(gòu)那一節(jié)的內(nèi)容,你就應(yīng)該知道上面這些目錄下放的是哪一類文件了免姿。通常這一類目錄下放的都是可執(zhí)行文件饼酿,當(dāng)我們在 Shell 中執(zhí)行一個命令時,系統(tǒng)就會按照 PATH 中設(shè)定的路徑按照順序依次到目錄中去查找胚膊,如果存在同名的命令故俐,則執(zhí)行先找到的那個。
下面我們將練習(xí)創(chuàng)建一個最簡單的可執(zhí)行 Shell 腳本和一個使用 C 語言創(chuàng)建的"hello world"程序紊婉,如果這兩部分內(nèi)容你之前沒有學(xué)習(xí)過药版,那么你可以進(jìn)行一個入門學(xué)習(xí): C 語言入門教程 高級 Bash 腳本編程指南 Linux Shell Scripting Tutorial (LSST) v2.0
創(chuàng)建一個 Shell 腳本文件:$ vim hello_shell.sh
在腳本中添加如下內(nèi)容,保存并退出(注意不要省掉第一行喻犁,這不是注釋槽片,論壇有用戶反應(yīng)會有語法錯誤何缓,就是因為沒有了第一行):
#!/bin/zsh
for ((i=0; i<10; i++));do
echo "hello shell"
done
exit 0
為文件添加可執(zhí)行權(quán)限:$ chmod 755 hello_shell.sh
執(zhí)行腳本$ ./hello_shell.sh
創(chuàng)建一個 C 語言"hello world"程序:$ vim hello_world.c
#include <stdio.h>
int main(void)
{
printf("hello world!\n");
return 0;
}
使用 gcc 生成可執(zhí)行文件:$ gcc -o hello_world hello_world.c
gcc 生成二進(jìn)制文件默認(rèn)具有可執(zhí)行權(quán)限,不需要修改
在 shiyanlou 家目錄創(chuàng)建一個mybin目錄还栓,并將上述 hello_shell.sh 和 hello_world 文件移動到其中:$ mkdir mybin$ mv hello_shell.sh hello_world mybin/
現(xiàn)在你可以在mybin目錄中分別運行你剛剛創(chuàng)建的兩個程序:
$ cd mybin
$ ./hello_shell.sh
$ ./hello_world
![](https://dn-anything-about-doc.qbox.me/linux_base/5-6.png/logoblackfont)
回到上一級目錄碌廓,也就是shiyanlou家目錄,當(dāng)再想運行那兩個程序時剩盒,會發(fā)現(xiàn)提示命令找不到谷婆,除非加上命令的完整路徑,但那樣很不方便辽聊,如何做到想使用系統(tǒng)命令一樣執(zhí)行自己創(chuàng)建的腳本文件或者程序呢纪挎?那就要將命令所在路徑添加到PATH環(huán)境變量了。
4.添加自定義路徑到“PATH”環(huán)境變量
在前面我們應(yīng)該注意到PATH里面的路徑是以:作為分割符跟匆,所以我們可以這樣添加自定義路徑:$ PATH=$PATH:/home/shiyanlou/mybin
注意這里一定要使用絕對路徑
現(xiàn)在你就可以在其他任意目錄執(zhí)行那兩個命令了(注意需要去掉前面的./
)异袄。你可能會意識到這樣還并沒有很好的解決問題,因為我給 PATH 環(huán)境變量追加了一個路徑玛臂,它也只是在當(dāng)前 Shell 有效烤蜕,我一旦退出終端,再打開就會發(fā)現(xiàn)又失效了垢揩。有沒有方法讓添加的環(huán)境變量全局有效玖绿?或者每次啟動 Shell 時自動執(zhí)行上面添加自定義路徑到 PATH 的命令敛瓷?下面我們就來說說后一種方式——讓它自動執(zhí)行叁巨。
在每個用戶的 home 目錄中有一個 Shell 每次啟動時會默認(rèn)執(zhí)行一個配置腳本,以初始化環(huán)境呐籽,包括添加一些用戶自定義環(huán)境變量等等锋勺。zsh 的配置文件是.zshrc,相應(yīng) Bash 的配置文件為.bashrc
狡蝶。
它們在etc下還都有一個或多個全局的配置文件庶橱,不過我們一般只修改用戶目錄下的配置文件。我們可以簡單的使用下面命令直接添加內(nèi)容到.zshrc中:
$ echo "PATH=$PATH:/home/shiyanlou/mybin" >> .zshrc
上述命令中>>表示將標(biāo)準(zhǔn)輸出以追加的方式重定向到一個文件中贪惹,注意前面用到的>是以覆蓋的方式重定向到一個文件中苏章,使用的時候一定要注意分辨。在指定文件不存在的情況下都會創(chuàng)建新的文件奏瞬。
5.修改和刪除已有變量
-
變量修改
變量的修改有以下幾種方式:
比如要修改我們前面添加到 PATH 的環(huán)境變量枫绅。為了避免操作失誤導(dǎo)致命令找不到,我們先將 PATH 賦值給一個新的自定義變量 path:
$ path=$PATH
$ echo $path
$ path=${path%/home/shiyanlou/mybin}
# 或使用通配符,*表示任意多個任意字符$ path=${path%*/mybin}
- 變量刪除
可以使用unset命令刪除一個環(huán)境變量:
$ unset temp
6.如何讓環(huán)境變量立即生效
在上面我們在 Shell 中修改了一個配置腳本文件之后(比如 zsh 的配置文件 home 目錄下的.zshrc)硼端,每次都要退出終端重新打開甚至重啟主機(jī)之后其才能生效并淋,很是麻煩,我們可以使用source命令來讓其立即生效珍昨,如:
$ source .zshrc
source命令還有一個別名就是 . 县耽,注意與表示當(dāng)前路徑的那個點區(qū)分開句喷,雖然形式一樣,但作用和使用方式一樣兔毙,上面的命令如果替換.的方式就該是
$ . ./.zshrc
注意第一個點后面有一個空格唾琼,而且后面的文件必須指定完整的絕對或相對路徑名,source 則不需要澎剥。
二父叙、搜索文件
與搜索相關(guān)的命令常用的有如下幾個whereis,which,find,locate。
whereis簡單快速
$whereis who
![](https://dn-anything-about-doc.qbox.me/linux_base/5-7.png)
你會看到它找到了三個路徑肴裙,兩個可執(zhí)行文件路徑和一個 man 在線幫助文件所在路徑趾唱,這個搜索很快,因為它并沒有從硬盤中依次查找蜻懦,而是直接從數(shù)據(jù)庫中查詢甜癞。whereis只能搜索二進(jìn)制文件(-b),man幫助文件(-m)和源代碼文件(-s)宛乃。如果想要獲得更全面的搜索結(jié)果可以使用locate命令悠咱。
locate快而全
通過"/var/lib/mlocate/mlocate.db"數(shù)據(jù)庫查找,不過這個數(shù)據(jù)庫也不是實時更新的征炼,系統(tǒng)會使用定時任務(wù)每天自動執(zhí)行updatedb命令更新一次析既,所以有時候你剛添加的文件,它可能會找不到谆奥,需要手動執(zhí)行一次updatedb命令(在我們的環(huán)境中必須先執(zhí)行一次該命令)眼坏。它可以用來查找指定目錄下的不同文件類型,如查找 /etc 下所有以 sh 開頭的文件:
$ locate /etc/sh
注意,它不只是在 etc 目錄下查找并會自動遞歸子目錄進(jìn)行查找
查找 /usr/share/ 下所有 jpg 文件:
$ locate /usr/share/*.jpg
注意要添加號前面的反斜杠轉(zhuǎn)義酸些,否則會無法找到*
如果想只統(tǒng)計數(shù)目可以加上-c參數(shù)宰译,-i參數(shù)可以忽略大小寫進(jìn)行查找,whereis 的-b,-m魄懂,-s同樣可以是使用沿侈。
which小而精
which本身是 Shell 內(nèi)建的一個命令,我們通常使用which來確定是否安裝了某個指定的軟件市栗,因為它只從PATH環(huán)境變量指定的路徑中去搜索命令:
$ which man
find精而細(xì)
find應(yīng)該是這幾個命令中最強大的了缀拭,它不但可以通過文件類型、文件名進(jìn)行查找而且可以根據(jù)文件的屬性(如文件的時間戳填帽,文件的權(quán)限等)進(jìn)行搜索蛛淋。find命令強大到,要把它將明白至少需要單獨好幾節(jié)課程才行盲赊,我們這里只介紹一些常用的內(nèi)容铣鹏。在指定目錄下搜索指定文件名的文件:
$ find /etc/ -name interfaces
注意 find 命令的路徑是作為第一個參數(shù)的, 基本命令格式為 find [path] [option] [action]
與時間相關(guān)的命令參數(shù):
下面以-mtime參數(shù)舉例:
![](https://dn-anything-about-doc.qbox.me/linux_base/5-8.png)
列出 home 目錄中哀蘑,當(dāng)天(24 小時之內(nèi))有改動的文件:
$ find ~ -mtime 0
列出用戶家目錄下比Code文件夾新的文件:
$ find ~ -newer /home/shiyanlou/Code
- 娛樂環(huán)節(jié):文字雨
sudo apt-get update;sudo apt-get install cmatrix
直接敲指令cmatrix就可以運行了诚卸, 你可以修改一下文字顏色 裝逼效果更佳