一、退出狀態
- 進程通過退出狀態報告進程運行成功或失敗
-
echo $?
查看上一條命令執行的退出狀態 - 0代表運行成功,1-255代表運行失敗
-
exit [n]
自定義退出狀態碼 - 如果未指定退出狀態碼,腳本運行結束后的退出狀態碼為執行腳本最后一條命令的退出狀態碼
- 實驗:
(一)編寫腳本error.sh,代碼如下:
# /bin/bash
#
pwd
cmd
exit 100
執行結果如下:
由于沒有cmd這條命令,所以腳本運行報錯,退出狀態碼為指定的100。
(二)改動腳本error.sh,改動后的代碼如下:
# /bin/bash
#
pwd
cmd
(exit 100)
echo hello
執行結果如下:
發現雖然設置了exit命令,但之后的命令仍然被執行。原因在于將exit命令放置在小括號中,小括號的意義為在當前進程中新增子進程,exit命令的作用變為退出error.sh進程創建的子進程,父進程仍舊正常運行。
二、算術運算
- 運算符號:+(加),-(減),*(乘),/(除),%(取余),**(乘方)
- 實現算數運算的方法
- let var=算術表達式
- var=$[算術表達式]
- var=$((算術表達式))
- var=$(expr arg1 arg2 arg3 ...)
- declare -i var=算術表達式
- echo 算術表達式 | bc
- let用法
- $[]和$(())用法
- expr用法
- declare -i用法
- 乘法*符號有時需要轉義
- bash內建有隨機數生成器$RANDOM,可以用于生成一定范圍的隨機數,如生成2-50的隨機數$[$RANDOM%49+2]
- 增強型賦值:+=,-=,*=,/=,%=,例如a+=3等于a=a+3,其他符號類似
- 自增、自減:++,--,例如a++,b--
- 自增自減運算符在變量前后可能導致不同的結果,運算符在前如++a表示對變量a自增1再進行其他操作,運算符在后如b--表示對變量b先進行其他操作再自減1
三、邏輯運算
- 邏輯運算的結果只有true或false,但是不同情況下對true或false的數字描述不同
- 與運算:只有均為true,結果才為true,否則結果均為false
- 或運算:只有均為false,結果才為false,否則結果均為true
- 非運算:true取非結果為false,false取非結果為true
- 短路與 &&:第一個為0,第二個跳過計算,結果一定為0;
第一個為1,繼續計算第二個,才能計算出結果 - 短路或 ||: 第一個為1,第二個跳過計算,結果一定為1;
第一個為0,繼續計算第二個,才能計算出結果 - 異或^:相同為假,不同為真,異或可以用于交換兩個值
四、條件測試
(一)測試命令
- test expression
- [ expression]
- [[ expression ]]
- 括號內的expression前后都需要有空格
- COMMAND1 && COMMAND2,COMMAND1為真時執行COMMAND2
- COMMAND1 || COMMAND2,COMMAND1為假時執行COMMAND2
- COMMAND1 && COMMAND2 || COMMAND3,可以實現當COMMAND1執行結果為真時,執行COMMAND2;當COMMAND1執行結果為假時,執行COMMAND3
(二)數值測試
-v VAR 變量VAR是否設置
-eq 是否等于
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于
-ne 是否不等于
實驗:實現當磁盤利用率超過80%時,自動報警
代碼如下:
#! /bin/bash
#
diskusage=`df | grep "/dev/sd" | grep -o "[0-9]\{1,3\}%" | tr -d % | sort -nr | head -1`
[ "$diskusage" -ge 80 ] && echo "disk will be full"
- 執行結果如下:
(三)字符串測試
- == 是否等于
- > 是否大于
- < 是否小于
- != 是否不等于
- =~ pattern 是否匹配正則表達式,正則表達式為擴展正則表達式
- -z "string" 字符串是否為空,空為真,非空為假
- -n "string" 字符串是否非空,非空為真,空為假
- 字符串測試中的操作數都需要打引號,才能確保結果正確
- 可以看出變量var非空時為真,空時為假
- 變量abc為空,測試時使用-n選項應該非空為真,空為假,不會執行第二條命令打印true。但是當變量未有引號包含時,執行打印true,顯然不對。變量有引號包含后,第二條命令不運行,符合預期。所以在字符串測試中一定要對變量打引號。
(四)文件測試
-
存在性測試
- -a 或-e 存在為真,不存在為假
-
類別測試
- -f 是否存在且為普通文件
- -d 是否存在且為目錄文件
- -h 或 -L 是否存在且為符號鏈接文件
- -b 是否存在且為塊設備文件
- -c 是否存在且為字符設備文件
- -p 是否存在且為管道文件
- -s 是否存在且為套接字文件
- 判斷文件類型時,遇到軟鏈接文件會直接判斷鏈接的源文件類型,所以要先判斷是否為軟鏈接文件
- 實驗:
-
文件權限測試
- -r 是否存在且可讀
- -w 是否存在且可寫
- -x 是否存在且可執行
-
文件特殊權限測試
- -u 是否存在且擁有suid權限
- -g 是否存在且擁有sgid權限
- -k 是否存在且擁有sticky權限
實驗:判斷文件后綴是否為.sh,若是則判斷其是否具有可執行權限,若是則退出,否則為其增加可執行權限
- 文件大小測試
- -s 文件是否存在且非空
- 文件屬性測試
- -O 文件上一次被讀取后是否被修改過,即mtime是否新于atime
- -U 當前用戶是否為文件屬主
- -G 當前用戶是否為文件屬組
(五)雙目測試
- file1 -ef file2 兩個文件是否屬于相同分區同一個inode號
- file1 -nt file2 file1是否新于file2,比較mtime
- file1 -ot file2 file1是否舊于file2,比較mtime
- 實驗:驗證兩個文件是否同一個inode號
(六) 組合測試
- 第一種方式:
COMMAND1 && COMMAND2 并且
COMMAND1 || COMMAND2 或者
!COMMAND 非 - 第二種方式(只在組合測試命令時使用):
expression1 -a expression2 并且
expression1 -o expression2 或者
!expression 非
五、read 將輸入分配給一個或多個變量
- -p 指定要顯示的提示
- -s 靜默輸入,用于密碼輸入
- -n N 指定輸入的字符長度N
- -d char 自定輸入的結束符
- -t N timeout為N秒
- read從標準輸入讀入多個單詞,每個單詞一個變量,若變量個數少于單詞數,則多出的單詞也賦給最后一個變量
- 實驗
六、bash展開命令行的順序
- 把命令行分成單個命令詞
- 展開別名
- 展開大括號的聲明({})
- 展開波浪符聲明(~)
- 命令替換($()和``)
- 再次把命令行分成命令詞
- 展開文件通配(*、?、[abc]等等)
- 準備I/0重導向(<、>)
- 運行命令
七、bash的配置文件
- 全局配置文件
- /etc/profile
- /etc/profile.d/*.sh
- /etc/bashrc
- 個人配置文件
- ~/bash_profile
- ~/bashrc
- 交互式登錄:終端輸入賬號密碼登錄或者
su - username
登錄
配置文件執行順序:/etc/profile -> /etc/profile.d/*.sh -> ~/bash_profile -> ~/bashrc -> /etc/bashrc - 非交互式登錄:圖形終端登錄、
su username
登錄、執行腳本
配置文件執行順序:~/bashrc -> /etc/bashrc -> /etc/profile.d/*.sh - profile類文件配置功能
- 定義環境變量
- 運行腳本
- bashrc類文件配置功能
- 定義命令別名和函數
- 定義本地變量
- 配置文件生效
- 重啟shell進程
-
.
或者source
八、bash的退出任務
- 退出任務保存在
~/bash_logout
文件中 - 在退出登錄的shell時運行
~/bash_logout
文件 - 可用于退出后創建自動備份、清除臨時文件等功能
九、$- 變量
- h:hashall,打開這個選項后,Shell會將命令所在的路徑hash下來,避免每次都要查詢。通過set +h將h選項關閉
- i:interactive-comments,包含這個選項說明當前的shell是一個交互式的shell。在腳本中,i選項是關閉的
- m:monitor,打開監控模式,就可以通過Job control來控制進程的停止、繼續,后臺或者前臺執行等
- B:braceexpand,大括號擴展
- H:history,H選項打開,可以展開歷史列表中的命令,可以通過!感嘆號來完成,例如“!!”返回上最近的一個歷史命令,“!n”返回第n 個歷史命令