- 選擇執(zhí)行:if語句
- 條件判斷:case語句
- 循環(huán)控制:for語句
- 循環(huán)控制:while語句和until語句
- 循環(huán)控制:continue, break, shift語句
- 循環(huán)控制:select語句
- 信號捕捉:trap語句
一、選擇執(zhí)行:if 語句
- 單分支
if 判斷條件; then
判斷條件為真的代碼
fi
- 雙分支
if 判斷條件; then
判斷條件為真的代碼
else
判斷條件為假的代碼
fi
- 多分支:逐條件判斷,直到滿足條件執(zhí)行分支代碼,忽略之后的條件判斷
if 判斷條件1; then
判斷條件1為真的代碼
elif 判斷條件2; then
判斷條件2為真的代碼
elif 判斷條件3; then
判斷條件3為真的代碼
...
else
上述所有條件為假的代碼
fi
- 實驗:當(dāng)運行腳本時已經(jīng)自帶參數(shù),輸出參數(shù)值;若運行腳本時沒有自帶參數(shù),則提示輸入?yún)?shù),并輸出參數(shù)值
#! /bin/bash
if [ $# -eq 0 ] ;then
read -p "please type the words: " words
else
words=$*
fi
echo $words

二、條件判斷:case 語句
- 語法:
case 變量引用 in
PAT1)
分支語句1
;;
PAT2)
分支語句2
;;
PAT3)
分支語句3
;;
...
*)
默認(rèn)分支語句
;;
esac
PAT:支持glob通配符
*:任意長度任意字符
?:任意單個字符
[]:指定范圍內(nèi)的任意單個字符
a|b:a或b實現(xiàn)一個菜單:
| 序號 | 菜名 | 價格 |
|---|---|---|
| 1 | lamian | 10 |
| 2 | huimian | 10 |
| 3 | yangroutang | 20 |
| 4 | gaifan | 15 |
| 5 | jiaozi | 20 |
要求輸入菜名序號后,顯示出相應(yīng)菜品的價格
#! /bin/bash
cat <<eof
menu:
1) lamian
2) huimian
3) yangroutang
4) gaifan
5) jiaozi
eof
read -p "choose your menu(eg:1): " menu
case $menu in
1|2)
echo "menu $menu price is 10"
;;
3|5)
echo "menu $menu price is 20"
;;
4)
echo "menu $menu price is 15"
;;
*)
echo "wrong menu"
;;
esac

三、循環(huán)控制:for 語句
- 循環(huán)結(jié)構(gòu)的基本組成:初始值、循環(huán)開始和結(jié)束條件、循環(huán)體
(1)基本用法:
- 語法:
for 變量名 in 列表; do
循環(huán)體
done
執(zhí)行機制:
依次將列表中的元素賦值給“變量名”; 每次賦值后即執(zhí)行一次循環(huán)體; 直到列表中的元素耗盡,循環(huán)結(jié)束-
列表生成方式:
- 直接給出列表
- 整數(shù)列表: {start..end}, {start..end...step}
- 返回列表的命令:$(COMMAND) 或 `COMMAND`,如 $(seq start step end)
- 使用glob:*.sh
- 變量引用:$@, $*
(2)特殊用法(雙小括號方法):
雙小括號法:用兩組括號嵌套
(()),可以實現(xiàn)C語言風(fēng)格變量操作,如
let i++等同于((i++))-
for 循環(huán)的特殊格式
- 語法:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式)); do
循環(huán)體
done
控制變量初始化:僅當(dāng)運行到循環(huán)代碼段開始時執(zhí)行一次
控制變量的修正表達式:每輪循環(huán)結(jié)束會先進行控制變量修正運算,而后再做條件判斷
實驗:建立一個10*10矩陣,每個位置以“行號.列號”方式命名,如第1行第3列的內(nèi)容為1.3
#! /bin/bash
for i in {1..10}; do
for j in {1..10}; do
echo -ne "$i.$j\t"
done
echo
done
***另一種實現(xiàn)***
#! /bin/bash
for ((i=1;i<=10;i++));do
for ((j=1;j<=10;j++));do
echo -ne "$i.$j\t"
done
echo
done

四、循環(huán)控制:while 語句和until 語句
(1)while 語句
- 語法:
while CONDITON ; do
循環(huán)體
done
CONDITION 循環(huán)控制條件
值為true或false,只有為true時才能執(zhí)行循環(huán)體,一般在循環(huán)體中有循環(huán)控制變量在每一次循環(huán)中變化,最終使CONDITION值由true轉(zhuǎn)變?yōu)閒alse,從而終止循環(huán)進入條件:CONDITION=true
退出條件:CONDITION=false無限循環(huán):
while true; do
COMMANDs
done
- 特殊用法:遍歷文件的每一行
while read line ; do
循環(huán)體
done < /path/to/file //依次讀取/path/to/file文件的每一行,并將行復(fù)制給變量line
- 實驗:判斷/etc/passwd文件每個用戶是系統(tǒng)用戶還是普通用戶(CentOS 7)
#! /bin/bash
while read userline; do
userid=`echo $userline | cut -d: -f3`
username=`echo $userline | cut -d: -f1`
if (( userid < 1000 )); then
echo "$username is system user"
else
echo "$username is common user"
fi
done < /etc/passwd

(2)until 語句
- 語法:
until CONDITION ; do
循環(huán)體
done
CONDITION循環(huán)控制條件
值為false時執(zhí)行循環(huán)體,當(dāng)值為true時,終止循環(huán)進入條件:CONDITION=false
退出條件:CONDITION=true無限循環(huán):
until false; do
COMMANDs
done
五、循環(huán)控制:continue, break, shift語句
(1)continue 語句
continue [N]:提前結(jié)束第N層的本輪循環(huán),而直接進入下一輪判斷
最內(nèi)層為第1層不寫層數(shù)默認(rèn)為第1層
在循環(huán)體中使用,語法:
while CONDITION1; do
CMD1
...
if CONDITION2; then
continue //continue命令表示跳出本輪循環(huán),直接下一輪循環(huán)開始判斷CONDITION1值
fi
CMDn
...
done
- 實驗:輸出與上文類似的10*10矩陣,但是行號與列號相同的位置為空白
#! /bin/bash
for i in {1..10}; do
for j in {1..10}; do
[ $j -eq $i ] && { echo -ne "\t";continue; } //行號與列號相同時,輸出制表符,跳出本輪循環(huán)
echo -ne "$i.$j\t"
done
echo
done

(2)break 語句
break [N]:提前結(jié)束第N層循環(huán)
最內(nèi)層為第1層不寫層數(shù)默認(rèn)為第1層
在循環(huán)體中使用,語法:
while CONDITION1; do
CMD1
...
if CONDITION2; then
break //continue命令表示跳出本層循環(huán),執(zhí)行本層循環(huán)外的語句
fi
CMDn
...
done
- 實驗:輸出與上文類似的10*10矩陣,但是列號大于等于行號的位置為空白
#! /bin/bash
for i in {1..10}; do
for j in {1..10}; do
[ $j -eq $i ] && break //行號與列號相同時,終止本層循環(huán),故列號大于行號的位置也沒有機會輸出
echo -ne "$i.$j\t"
done
echo
done

(3)shift 語句
語法:
shift [N]用于將參數(shù)列表左移N次,缺省為左移一次
參數(shù)列表一旦被移動,最左端的那個參數(shù)就從列表中刪除
while 循環(huán)遍歷位置參量列表時,常用到shift
實驗:
(1)輸入n個參數(shù),第1行輸出第1-n個參數(shù),第2行輸出第2-n個參數(shù),以此類推,直到第n行輸出第n個參數(shù)
#! /bin/bash
while [ $# -gt 0 ]; do
echo "$*"
shift
done

(2)輸入n個參數(shù),每行輸出一個參數(shù)
#! /bin/bash
until [ -z "$1" ];do
echo "$1"
shift
done

六、循環(huán)控制:select 語句
- 語法:
select variable in list; do
循環(huán)體命令
done
select 循環(huán)主要用于創(chuàng)建菜單,按數(shù)字順序排列的菜單項將顯示在標(biāo)準(zhǔn)錯誤上,并顯示PS3 提示符,等待用戶輸入
用戶輸入菜單列表中的某個數(shù)字,執(zhí)行相應(yīng)的命令
用戶輸入被保存在內(nèi)置變量REPLY 中
select是個無限循環(huán),因此要記住用break命令退出循環(huán),或用exit命令終止腳本,也可以按ctrl+c退出循環(huán)
select經(jīng)常和case聯(lián)合使用
實驗:實現(xiàn)一個菜單,輸入菜單編號顯示價格,不存在的菜單號顯示"wrong menu"并退出
| 序號 | 菜名 | 價格 |
|---|---|---|
| 1 | lamian | 10 |
| 2 | huimian | 10 |
| 3 | yangroutang | 20 |
| 4 | gaifan | 15 |
| 5 | jiaozi | 20 |
#! /bin/bash
PS3="please type the menu num: " //環(huán)境變量PS3指定提示符格式
select menu in lamian huimian rangroutang gaifan jiaozi; do
case $REPLY in //用戶的輸入自動存入REPLY變量中
1)
echo "the price of lamian is \$10"
;;
2)
echo "the price of huimian is \$10"
;;
3)
echo "the price of rangroutang is \$20"
;;
4)
echo "the price of gaifan is \$15"
;;
5)
echo "the price of jiaozi is \$20"
;;
*)
echo "wrong menu"
break //select語句默認(rèn)無限循環(huán),需要有break命令退出循環(huán)
;;
esac
done

七、信號捕捉:trap 語句
trap '觸發(fā)指令' 信號
進程收到系統(tǒng)發(fā)出的信號后,執(zhí)行觸發(fā)指令,而不執(zhí)行信號操作trap ' ' 信號
進程收到系統(tǒng)發(fā)出的信號后,直接忽略trap '-' 信號
進程收到系統(tǒng)發(fā)出的信號后,恢復(fù)信號操作
*trap -p
列出自定義信號操作
- 實驗:trap語句驗證,以信號2 SIGINT為例
#! /bin/bash
trap 'echo "signal:sigint"' sigint //接到sigint信號輸出"signal:sigint"
trap -p
for (( i=1;i<=5;i++ )); do
echo $i
sleep 2
done
trap ' ' sigint //接到sigint信號直接忽略
trap -p
for (( j=6;j<=10;j++ )); do
echo $j
sleep 2
done
trap '-' sigint //接到sigint信號恢復(fù)信號操作
trap -p
for (( k=11;k<=15;k++ )); do
echo $k
sleep 2
done

共3個循環(huán),每個循環(huán)開始前都輸出了相應(yīng)的自定義信號情況
輸出1-5時,Ctrl+C發(fā)出sigint信號后,直接執(zhí)行替換的命令echo "signal:sigint,循環(huán)繼續(xù)
輸出6-10時,Ctrl+C發(fā)出sigint信號后,直接忽略信號,循環(huán)繼續(xù)
輸出11-15時,Ctrl+C發(fā)出sigint信號后,恢復(fù)信號本身作用,循環(huán)被終止