20170731 Shell 腳本編程基礎(二)

一、退出狀態

  • 進程通過退出狀態報告進程運行成功或失敗
  • 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 個歷史命令
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,572評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,071評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,409評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,569評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,360評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,895評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,979評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,123評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,643評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,559評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,742評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,250評論 5 356
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,981評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,363評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,622評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,354評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,707評論 2 370

推薦閱讀更多精彩內容