一、環境變量
1. 變量
變量就是計算機中用于記錄一個值(數值,字符或字符串)的符號。通常變量與值是一對一的關系,可以通過表達式讀取它的值并賦值給其它變量,也可以直接指定數值賦值給任意變量。大部分的編程語言會區分變量的類型,用于分別記錄數值、字符或者字符串等等數據類型。Shell 中的變量也基本如此,有不同類型(但不用專門指定類型名),可以參與運算,有作用域限定。
變量的作用域即變量的有效范圍(比如一個函數中、一個源文件中或者全局范圍),在該范圍內只能有一個同名變量。一旦離開則該變量無效,如同不存在這個變量一般。
在 Shell 中創建一個變量,給變量賦值和讀取變量的值:
使用 declare 命令創建一個變量名為 tmp 的變量:
$ declare tmp
其實也可以直接即用即創建, declare 在創建其它指定類型的變量(如數組)時會用到。
使用 = 號賦值運算符,將變量 tmp 賦值為 shiyanlou:
$ tmp=shiyanlou
讀取變量的值,使用 echo 命令和 $ 符號($ 符號用于表示引用一個變量的值):
$ echo $tmp
2. 環境變量
環境變量的作用域比自定義變量的要大,如 Shell 的環境變量作用于自身和它的子進程。在所有的 UNIX 和類 UNIX 系統中,每個進程都有其各自的環境變量設置,且默認情況下,當一個進程被創建時,處理創建過程中明確指定的話,它將繼承其父進程的絕大部分環境設置。Shell 程序也作為一個進程運行在操作系統之上,我們在 Shell 中運行的大部分命令都將以 Shell 的子進程的方式運行。
通常涉及到的變量類型有三種:
?當前 Shell 進程私有用戶自定義變量,如上面創建的 tmp 變量,只在當前 Shell 中有效。
?Shell 本身內建的變量。
?從自定義變量導出的環境變量。
三個與環境變量相關的命令:set,env,export。
這三個命令都是用于打印環境變量信息,區別在于涉及的變量范圍不同。詳見下表:
set 顯示當前 Shell 所有變量,包括其內建環境變量(與 Shell 外觀等相關),用戶自定義變量及導出的環境變量。
env 顯示與當前用戶相關的環境變量,還可以讓命令在指定環境中運行。
export 顯示從 Shell 中導出成環境變量的變量,也能通過它將自定義變量導出為環境變量。
可以直觀的使用 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 工具比較導出的幾個文件的內容:
簡單地理解,在當前進程的子進程有效則為環境變量,否則不是(有些人也將所有變量統稱為環境變量,只是以全局環境變量和局部環境變量進行區分,只要理解它們的實質區別即可)。用 export 命令來體會一下,先在 Shell 中設置一個變量 temp=shiyanlou,然后再新創建一個子 Shell 查看 temp 變量的值:

注意:為了與普通變量區分,習慣將環境變量名設為大寫。
永久生效
讓環境變量永久生效:
按變量的生存周期來劃分,Linux 變量可分為兩類:
1.永久的:需要修改配置文件,變量永久生效;
2.臨時的:使用 export 命令行聲明即可,變量在關閉 shell 時失效。
兩個重要文件 /etc/bashrc(有的 Linux 沒有這個文件) 和 /etc/profile ,它們分別存放的是 shell 變量和環境變量。要注意區別的是每個用戶目錄下的一個隱藏文件:
.profile可以用 ls -a 查看
cd /home/shiyanlou
ls -a
.profile只對當前用戶永久生效。而寫在 /etc/profile 里面的是對所有用戶永久生效,如果想要添加一個永久生效的環境變量,只需要打開 /etc/profile,在最后加上想添加的環境變量就好啦。
3. 命令的查找路徑與順序
在 Shell 中輸入一個命令,Shell 通過環境變量 PATH 來進行搜索, PATH 里面保存了 Shell 中執行的命令的搜索路徑。
查看 PATH 環境變量的內容:
$ echo $PATH
默認情況下會看到如下輸出:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
通常這一類目錄下放的是可執行文件,當在 Shell 中執行一個命令時,系統就會按照 PATH 中設定的路徑按照順序依次到目錄中去查找,如果存在同名的命令,則執行先找到的那個。
創建一個最簡單的可執行 Shell 腳本和一個使用 C 語言創建的“ hello world ”程序
創建一個 Shell 腳本文件:
$ gedit hello_shell.sh
在腳本中添加如下內容,保存并退出(注意不要省掉第一行,這不是注釋,如有語法錯誤,是因為沒有了第一行):
#!/bin/bash
for ((i=0; i<10; i++));do
echo "hello shell"
done
exit 0
為文件添加可執行權限:
$ chmod 755 hello_shell.sh
執行腳本:
$ ./hello_shell.sh
創建一個 C 語言“ hello world ”程序:
$ gedit hello_world.c
#include
int main(void)
{
printf("hello world!\n");
return 0;
}
保存后使用 gcc 生成可執行文件:
$ gcc -o hello_world hello_world.c
gcc 生成二進制文件默認具有可執行權限,不需要修改
在 shiyanlou 家目錄創建一個 mybin 目錄,并將上述 hello_shell.sh 和 hello_world 文件移動到其中:
$ mkdir mybin
$ mv hello_shell.sh hello_world mybin/
現在可以在 mybin 目錄中分別運行剛剛創建的兩個程序:
$ cd mybin
$ ./hello_shell.sh
$ ./hello_world
回到上一級shiyanlou 家目錄,再想運行那兩個程序時,會發現提示命令找不到,除非加上命令的完整路徑,將命令所在路徑添加到 PATH 環境變量,就可以像使用系統命令一樣執行自己創建的腳本文件或者程序了。
4. 添加自定義路徑到“ PATH ”環境變量
PATH 里面的路徑是以 : 作為分割符的,可以這樣添加自定義路徑:
$ PATH=$PATH:/home/shiyanlou/mybin
注意這里一定要使用絕對路徑。
現在就可以在任意目錄執行那兩個命令了(注意需要去掉前面的 ./)。給PATH 環境變量追加了一個路徑,它也只是在當前 Shell 有效,一旦退出終端,再打開就會發現又失效了。讓它自動執行可以讓添加的環境變量全局有效,或者每次啟動 Shell 時自動執行上面添加自定義路徑到 PATH 的命令。
在每個用戶的 home 目錄中有一個 Shell 每次啟動時會默認執行一個配置腳本,以初始化環境,包括添加一些用戶自定義環境變量等等。zsh 的配置文件是 .zshrc,相應 Bash 的配置文件為 .bashrc 。它們在 etc 下還都有一個或多個全局的配置文件,不過我們一般只修改用戶目錄下的配置文件。
簡單地使用下面命令直接添加內容到 .zshrc 中:
$ echo "PATH=$PATH:/home/shiyanlou/mybin" >> .zshrc
上述命令中 >> 表示將標準輸出以追加的方式重定向到一個文件中,注意前面用到的 > 是以覆蓋的方式重定向到一個文件中。在指定文件不存在的情況下都會創建新的文件。
5. 修改和刪除已有變量
變量修改
變量的修改有以下幾種方式:
變量設置方式? ? ? ? ? 說明
${變量名#匹配字串} 從頭向后開始匹配,刪除符合匹配字串的最短數據
${變量名##匹配字串} 從頭向后開始匹配,刪除符合匹配字串的最長數據
${變量名%匹配字串} 從尾向前開始匹配,刪除符合匹配字串的最短數據
${變量名%%匹配字串} 從尾向前開始匹配,刪除符合匹配字串的最長數據
${變量名/舊的字串/新的字串} 將符合舊字串的第一個字串替換為新的字串
${變量名//舊的字串/新的字串} 將符合舊字串的全部字串替換為新的字串
比如要修改前面添加到 PATH 的環境變量。為了避免操作失誤導致命令找不到,先將 PATH 賦值給一個新的自定義變量 path:
$ path=$PATH
$ echo $path
$ path=${path%/home/shiyanlou/mybin}
或使用通配符,表示任意多個任意字符
$ path=${path%/mybin}
變量刪除
可以使用 unset 命令刪除一個環境變量:
$ unset temp
6. 如何讓環境變量立即生效
在 Shell 中修改了一個配置腳本文件之后(比如 zsh 的配置文件 home 目錄下的 .zshrc),可以使用 source 命令來讓其立即生效,如:
$ source .zshrc
source 命令還有一個別名就是.,注意與表示當前路徑的那個點區分開,雖然形式一樣,但作用和使用方式一樣,上面的命令如果替換成 . 的方式就該是:
$ . ./.zshrc
注意第一個點后面有一個空格,而且后面的文件必須指定完整的絕對或相對路徑名,source 則不需要。
二、搜索文件
與搜索相關的命令常用的有 whereis,which,find 和 locate 。
?whereis 簡單快速
$whereis who
找到了三個路徑,兩個可執行文件路徑和一個 man 在線幫助文件所在路徑,這個搜索很快,它并沒有從硬盤中依次查找,而是直接從數據庫中查詢。whereis 只能搜索二進制文件(-b),man 幫助文件(-m)和源代碼文件(-s)。如果想要獲得更全面的搜索結果可以使用 locate 命令。
locate 快而全 通過“ /var/lib/mlocate/mlocate.db ”數據庫查找,不過這個數據庫也不是實時更新的,系統會使用定時任務每天自動執行 updatedb 命令更新一次,所以有時候剛添加的文件,它可能會找不到,需要手動執行一次 updatedb 命令(在我們的環境中必須先執行一次該命令)。它可以用來查找指定目錄下的不同文件類型,如查找 /etc 下所有以 sh 開頭的文件: $ locate /etc/sh
它不只是在 /etc 目錄下查找,還會自動遞歸子目錄進行查找。
查找 /usr/share/ 下所有 jpg 文件:
$ locate /usr/share/*.jpg
注意要添加 * 號前面的反斜杠轉義,否則會無法找到。
如果想只統計數目可以加上 -c 參數,-i 參數可以忽略大小寫進行查找,whereis 的 -b、-m、-s 同樣可以使用。
which 小而精 which 本身是 Shell 內建的一個命令,通常使用 which 來確定是否安裝了某個指定的軟件,因為它只從 PATH 環境變量指定的路徑中去搜索命令: $ which man
find 精而細 find 應該是這幾個命令中最強大的了,它不但可以通過文件類型、文件名進行查找而且可以根據文件的屬性(如文件的時間戳,文件的權限等)進行搜索。find 命令特別強大。 $ sudo find /etc/ -name interfaces 這條命令表示去 /etc/ 目錄下面 ,搜索名字叫做 interfaces 的文件或者目錄。這是 find 命令最常見的格式,find 的第一個參數是要搜索的地方。注意 find 命令的路徑是作為第一個參數的, 基本命令格式為 find [path] [option] [action] 。
與時間相關的命令參數:
參數? ? 說明
-atime 最后訪問時間
-ctime 最后修改文件內容的時間
-mtime 最后修改文件屬性的時間
以 -mtime 參數舉例:
?-mtime n:n 為數字,表示為在 n 天之前的“一天之內”修改過的文件
?-mtime +n:列出在 n 天之前(不包含 n 天本身)被修改過的文件
?-mtime -n:列出在 n 天之內(包含 n 天本身)被修改過的文件
?newer file:file 為一個已存在的文件,列出比 file 還要新的文件名
列出 home 目錄中,當天(24 小時之內)有改動的文件:
$ find ~ -mtime 0
列出用戶家目錄下比 Code 文件夾新的文件:
$ find ~ -newer /home/shiyanlou/Code
三、數字雨
滿屏幕代碼的“數字雨”,只需要一個命令 cmatrix 。
需要先安裝,因為 Ubuntu 沒有預裝:
$ sudo apt-get update;sudo apt-get install cmatrix
修改終端的主題配色,修改為黑底綠字,修改方法見下圖:
F11 可以全屏顯示。
四、作業
找出 /etc/ 目錄下的所有以 .list 結尾的文件。
圖片詳細版:http://t.cn/RaB7ODN