1. 環境變量
1.1 變量
shell 中的變量有不同類型,可參與運算,有作用域限定
變量的作用域即變量的有效范圍(比如一個函數中、一個源文件中或者全局范圍),在該范圍內只能有一個同名變量。一旦離開則該變量無效,如同不存在這個變量一般。
# 使用 declare 命令創建一個變量名為 tmp 的變量
declare tmp
tmp=hello
echo $tmp
1.2 環境變量
環境變量作用域比自定義變量要大,如 shell 的環境變量作用於自身和它的子進程。
在所有的 UNIX 和類 UNIX 系統中,每個進程都有其各自的環境變量設置,且默認情況下,當一個進程被創建時,處理創建過程中明確指定的話,它將繼承其父進程的絕大部分環境設置。
Shell 程序也作為一個進程運行在操作系統之上,而我們在 Shell 中運行的大部分命令都將以 Shell 的子進程的方式運行。
通常我們會涉及到的環境變量有三種:
- 當前 Shell 進程私有用戶自定義變量,如上面我們創建的 temp 變量,只在當前 Shell 中有效。
- Shell 本身內建的變量。
- 從自定義變量導出的環境變量。
也有三個與上述三種環境變量相關的命令 set,env,export,詳見下表:
命令 | 說明 |
---|---|
set | 顯示當前 Shell 所有環境變量,包括其內建環境變量(與 Shell 外觀等相關),用戶自定義變量及導出的環境變量 |
env | 顯示與當前用戶相關的環境變量,還可以讓命令在指定環境變量 |
export | 顯示從 Shell 中導出成環境變量的變量,也能通過它將自定義變量導出為環境變量 |
關於環境變量,可以簡單的理解成在當前進程的子進程是否有效,有效則為環境變量,否則不是。
tmp=hello
echo $temp
# 創建子 shell
bash
echo temp
#值為空表示該變量無效,退出子 shell
exit
export temp
bash
echo $temp
1.3命令的查找路徑與順序
在 Shell 中輸入一個命令,Shell 是怎么知道在哪去找到這個命令然后執行的呢?這是通過環境變量 PATH 來進行搜索的
#查看 PATH 環境變量的內容
echo $PATH
創建一個 SHELL 腳本文件:
vim hello_shell.sh
在腳本中添加如下內容,保存並退出
#!/bin/zsh
for ((i=0; i<10; i++));do
echo "hello shell"
done
exit 0
為文件添加可執行權限:
chomd 755 hello_shell.sh
執行腳本
./ hello_shell.sh
創建一個 C 語言 hello world 程序:
vim hello_world.c
#include <stdio.h>
int main(void)
{
printf("hello world!\n");
return 0;
}
使用 gcc 生成可執行文件:
gcc -o hello_world hello_world.c
gcc 生成二進制文件默認具有可執行權限,不需要修改
在 home 目錄創建一個 test 目錄,並將上述 hello_shell.sh 和 hello_world 文件移動到其中:
mkdir test
mv hello_shell.sh hello_world test/
現在你可以在 test 目錄中分別運行你剛剛創建的兩個程序:
cd mybin
./hello_shell.sh
./hello_world
回到 home 目錄,再次運行那兩個程序時,會發現提示命令找不到
1.4添加自定義路徑到 PATH 環境變量
PATH=$PATH:/home/test
它也只是在當前 Shell 有效,我一旦退出終端,再打開就會發現又失效了。
在每個用戶的 home 目錄中有一個 Shell 每次啟動時會默認執行一個配置腳本,以初始化環境,包括添加一些用戶自定義環境變量等等。zsh 的配置文件是.zshrc,相應 Bash 的配置文件為 .bashrc。它們在 etc 下還都有一個或多個全局的配置文件,不過我們一般只修改用戶目錄下的配置文件。
echo "PATH=$PATH:/home/test" >> .bashrc
1.5修改和刪除已有變量
變量的修改有以下幾種方式:
變量設置方式 | 說明 |
---|---|
${變量名#匹配字串} | 從頭向后開始匹配,刪除符合匹配字串的最短數據 |
${變量名##匹配字串} | 從頭向后開始匹配,刪除符合匹配字串的最長數據 |
${變量名%匹配字串} | 從尾向前開始匹配,刪除符合匹配字串的最短數據 |
${變量名%%匹配字串} | 從尾向前開始匹配,刪除符合匹配字串的最長數據 |
${變量名/舊的字串/新的字串} | 將符合舊字串的第一個字串替換為新的字串 |
${變量名//舊的字串/新的字串} | 將符合舊字串的全部字串替換為新的字串 |
path=$PATH
echo $path
path=${path%/home/test}
# 或使用通配符,*表示任意多個任意字符
path=${path%*/test}
1.6如何讓環境變量立即生效
source .bashrc
2.搜索文件
與搜索相關的命令常用的有如下幾個 whereis,which,find,locate。
2.1 whereis 簡單快速
whereis who
whereis 只能搜索二進制文件 (-b),man 幫助文件 (-m) 和源代碼文件 (-s)。如果想要獲得更全面的搜索結果可以使用 locate 命令。
2.2 locate 快而全
通過 "/var/lib/mlocate/mlocate.db" 數據庫查找,不過這個數據庫也不是實時更新的,系統會使用定時任務每天自動執行 updatedb 命令更新一次。
# 在 etc 目錄下查找並自動遞歸子目錄進行查找
locate /etc/sh
# 查找 /usr/share/ 下所有 jpg 文件
locate /usr/share/\*.jpg
如果想只統計數目可以加上 -c 參數,-i 參數可以忽略大小寫進行查找,whereis 的 -b,-m,-s 同樣可以是使用。
2.3 which 小而精
which man
2.4 find 精而細
find 應該是這幾個命令中最強大的了,它不但可以通過文件類型、文件名進行查找而且可以根據文件的屬性(如文件的時間戳,文件的權限等)進行搜索。
find /etc/ -name interfaces
注意 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