shell腳本進階
一、流程控制
流程控制語句,即用來實現對程序流程的選擇、循環和返回等進行控制的語句。
1.條件判斷
(1)if條件判斷
普通if條件判斷
格式:
嵌套if條件判斷
格式:
(2)case判斷
簡潔版多分支if語句,當if語句有多個elif時可以使用case語句代替,語言更簡潔容易理解。使用場景:判斷某個變量值是否為多種情形中的一種時使用。
格式:
示例:
執行結果:
2、循環
循環執行就是將循環體內的代碼重復運行多次;運行的次數由進入循環的條件和退出循環決定。
(1)for循環
格式:
列表:變量的取值範圍,可以是變量的取值範圍,也可以是某個變量的執行結果。
執行機制:
依次將列表中的元素賦值“變量名”,每次賦值即執行一次循環體,直到列表中的元素耗盡,循環結束。
註:for循環的特殊格式:for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式))
控制變量初始化:僅在運行到循環代碼段時執行一次
控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,而後再做條件判斷
(2)while循環
格式:
執行機制:
CONDITION:循環控制條件;進入循環之前,先做一次判斷;每一次循環之後會再次做判斷;條件為“true”,則執行一次循環;直到條件測試狀態為“false”終止循環
因此:CONDTION一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正
進入條件:CONDITION為true
退出條件:CONDITION為false
註:while的特殊用法:(遍歷文件的每一行)
格式:
在執行循環的時候依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line。
(3)until循環
格式:
進入條件:CONDITION 為false
退出條件:CONDITION 為true
(4)循環控制語句continue, break 以及shift
用於循環體內
continue 用於結束本輪循環,而進入下一輪循環
Break 用於結束整個循環 ,不會進入下一輪循環
shift用於將參數列表list左移指定次數,默認為一次,在處理參數不確定的情況下比較好用。
練習:
1)打印九九乘法表
shell腳本
2)打印等腰三角形
Shell腳本:
3、select循環與菜單
select 循環主要用於創建菜單,按獅子書序排列的菜單項將顯示在標準錯誤上,並顯示PS3提符,等待用戶輸入。
用戶輸入菜單列表中的某個數字,執行相應的命令
用戶輸入被保存在內置變量REPLY中
Select是個無限循環,因此要用break命令退出循環,或者用exit命令終止腳本,也可以適應ctrl +c退出循環
經常和case聯合使用
示例:
二、trap信號捕捉
trap ‘觸發指令‘ 信號
自定義進程收到系統發出的指定信號後,將執行觸發指令,而不會執行原操作
trap ‘‘ 信號
忽略信號的操作
trap ‘-‘ 信號
恢復原信號的操作
trap -p
列出自定義信號操作
示例:
三、函數
把一段具有獨立功能代碼封裝在一起,並給予命名,後續用到的時候,可以直接通過給定函數名來調用整體函數,使用函數可以實現代碼的重用和模式化編程。函數在形式上和shell程序在形式上是相似的,不同的是他不是一個單獨的進程,不能單獨運行,而是shell程序的一部分。
函數和shell程序比較相似,區別在於:
Shell程序是在子shell中運行
Shell函數是在當前shell中運行,因此在當前shell中,函數可以更改shell中的變量
1、定義函數
函數有兩部分組成:函數名和函數體
語法一:
語法二:
語法三:(最簡便也是最常見的)
2、函數使用
可在交互式環境下定義函數,即直接在bash命令行裏寫函數和調用函數
可將函數放在腳本文件中作為它的一部分,即可以再同一個腳本文件裏調用函數
可放在只包含函數的單獨文件中,即在其他shell腳本中可以調用這個文件。使用 . /path/to/functions_files 或者source /path/to/functions_files
函數調用很簡單:
無參數:function_name
有參數: funcation_name ar1 arg2 ……argN , 在函數體,可以使用$1,$2,…調用這些參數,還可以使用$*,[email protected]等特殊變量
函數的生命周期:被調用時創建,返回時終止
declare -f :查看系統裏的函數
3、函數返回值
函數有兩種返回值:
(1)使用echo等命令進行輸出
(2) 函數體中調用命令的輸出結果
函數的退出狀態碼:
(1) 默認取決於函數中執行的最後一條命令的退出狀態碼
(2) 自定義退出狀態碼,其格式為:
return 從函數中返回,用最後狀態命令決定返回值
return0 無錯誤返回。
return 1-255 有錯誤返回
4、函數變量
變量的作用域不同
環境變量:當前shell和子shell有效
本地變量:只在當前shell進程有效,為執行腳本會啟動專用子shell進程;因此,本地變量作用範圍是當前shell腳本程序文件,包括腳本中的函數
局部變量:函數的生命周期;函數結束時變量被自動銷毀
由於函數是在當前shell中執行,當函數體中有變量的時候,容易與函數體外的變量產生沖突,這時候可以使用局部變量。
在函數中定義局部變量的方法 :
local NAME=VALUE
5、函數遞歸
函數直接或間接調用自身
階乘示例:
6、環境函數
使函數子進程也可使用
聲明:export –f function_name
查看:export -f 或者declare -xf
函數練習示例:
編寫服務腳本/root/bin/testsrv.sh,完成如下要求
(1) 腳本可接受參數:start,stop, restart, status
(2) 如果參數非此四者之一,提示使用格式後報錯退出
(3) 如是start:則創建/var/lock/subsys/SCRIPT_NAME,並顯示“啟動成功”
考慮:如果事先已經啟動過一次,該如何處理?
(4) 如是stop:則刪除/var/lock/subsys/SCRIPT_NAME,並顯示“停止完成”
考慮:如果事先已然停止過了,該如何處理?
(5) 如是restart,則先stop, 再start
考慮:如果本來沒有start,如何處理?
(6) 如是status, 則如果/var/lock/subsys/SCRIPT_NAME文件存在,則顯示“SCRIPT_NAMEisrunning...”
如果/var/lock/subsys/SCRIPT_NAME文件不存在,則顯示“SCRIPT_NAMEis stopped...”
其中:SCRIPT_NAME為當前腳本名
#!/bin/bash . /etc/init.d/functions var=‘/var/lock/subsys/script_service‘ start() { if [ -e $var ] ;then echo "This service isalready running " else touch $var action " service startsucessfully " fi } stop () { if [ -e $var ] ;then rm -f $var action "service stop" else action "service is notrunning" false # echo "service is notrunning " fi } restart () { if [ -e $var ]; then sleep 0.5 #間隔時間 stop sleep 0.5 start else action "service notrunning" /bin/false sleep 0.5 start fi } status() { if [ -e $var ];then echo -e "\tThe service isrunning..." else echo -e "\tThe service isnot running..." fi } status() { if [ -e $var ];then echo -e "\t The serviceis running" else echo -e "\t The serviceis stopd" fi } case $1 in start) start ;; stop) stop ;; restart) restart ;; status) status ;; *) echo "Please enter thecorrect parameters (start|stop|restart|status)" esac
shell腳本進階