- ver: 1.0
- 博客:https://www.cnblogs.com/Rohn
- 本文介紹了Shell常用的結構化陳述句,
目錄
- 陣列
- 獲取陣列所有元素
- 獲取陣列元素個數
- 陣列合并
- 洗掉陣列元素
- 實體
- 選擇結構
- if-else陳述句
- 基本格式
- if-else
- if-elif-else
- case-in陳述句
- if-else陳述句
- 回圈結構
- while陳述句
- 死回圈
- until陳述句
- for陳述句
- C語言風格的 for 回圈
- for-in回圈
- select-in陳述句
- break
- continue
- while陳述句
- 函式
- 函式定義
- 函式呼叫
- 函式引數
陣列
陣列(Array)是若干資料的集合,其中的每一份資料都稱為元素(Element),
Bash只支持一維陣列(不支持多維陣列),初始化時不需要定義陣列大小,理論上可以存放無限量的資料,
與大部分編程語言類似,陣列元素的下標由0開始,
Shell陣列用括號來表示,元素用"空格"符號分割開,格式如下:
array_name=(ele1 ele2 ele3 ... elen)
Tips:賦值號
=兩邊不能有空格,必須緊挨著陣列名和陣列元素,
獲取陣列中的元素要使用下標[],下標可以是一個整數,也可以是一個結果為整數的運算式;當然,下標必須大于等于0,格式如下:
${array_name[index]}
Tips:
array_name是陣列名,index是下標,
Shell是弱型別的,它并不要求所有陣列元素的型別必須相同,例如:
arr=(10 24 'ddd' 'ab22' 5)
獲取陣列所有元素
使用@或*可以獲取陣列中的所有元素,格式如下:
${array_name[*]}
${array_name[@]}
獲取陣列元素個數
使用#來獲取陣列元素的個數,格式如下:
${#array_name[@]}
${#array_name[*]}
陣列合并
陣列合并,就是將兩個或兩個以上的陣列合并成一個個陣列,格式如下:
array_new=(${array1[@]} ${array2[@]}...${arrayn[@]})
array_new=(${array1[*]} ${array2[*]}...${arrayn[*]})
洗掉陣列元素
使用unset關鍵字來洗掉陣列元素,格式如下:
unset array_name[index]
如果不寫下標,則代表洗掉整個陣列所有元素,格式如下:
unset array_name
實體
測驗ip是否ping通
#!/usr/bin/env bash
# Author: Rohn
# Version: 1.0
# Create Time: 2020/06/13
# Test network connectivity
arr_num=(3 11 25 32 200)
for i in ${arr_num[*]}; do
ip=192.168.110.${i}
ping -c 1 $ip >/dev/null 2>&1
if [ $? -eq 0 ]; then
echo "${ip} is ok."
else
echo "${ip} is unreachable."
fi
done
選擇結構
Shell中的選擇結構(分支結構)有兩種形式,分別是 if-else和case-in陳述句,它們都根據命令的退出狀態來判斷條件是否成立,
if-else陳述句
基本格式
基本結構格式:
if condition; then
statement(s)
fi
condition是判斷條件,如果condition成立(回傳True),那么then后邊的陳述句將會被執行;如果 condition不成立(回傳False),那么不會執行任何陳述句,
Tips:最后必須以
fi來閉合,fi就是if倒過來拼寫,
if-else
如果有兩個分支,就可以使用if-else陳述句,格式:
if condition; then
statement1
else
statement2
fi
如果condition成立,那么then后邊的 statement1陳述句將會被執行;否則,執行else 后邊的statement2陳述句,
if-elif-else
當分支比較多時,可以使用if-elif-else 結構,格式:
if condition1; then
statement1
elif condition2;then
statement2
...
else
statementn
fi
Tips:
if和elif后邊都得跟著then,
陳述句的執行邏輯:
- 如果
condition1成立,那么執行statement1,如果不成立,則執行elif陳述句; - 如果
elif陳述句不成立,則執行else陳述句;
case-in陳述句
當分支較多,且判斷條件比較簡單時,推薦使用case-in陳述句,格式如下:
case expression in
pattern1)
statement1
;;
pattern2)
statement2
;;
...
*)
statementn
esac
expression表示運算式,既可以是一個變數、一個數字、一個字串,還可以是一個數學計算運算式,或者是命令的執行結果,只要能夠得到expression的值就可以,pattern表示匹配模式,可以是一個數字、一個字串,甚至是一個簡單的正則運算式,
case會將expression的值與 pattern1、pattern2...patternn逐個進行匹配:
- 如果
expression和某個模式(比如 pattern2)匹配成功,就會執行這模式(比如 pattern2)后面對應的所有陳述句(該陳述句可以有一條,也可以有多條),直到遇見雙分號;;才停止;然后整個case-in陳述句就執行完了,程式會跳出整個case-in陳述句,執行esac后面的其它陳述句, - 如果 expression 沒有匹配到任何一個模式,那么就執行
*)后面的陳述句(*表示其它所有值),直到遇見雙分號;;或者esac才結束,*)相當于多個if分支陳述句中最后的else部分,
Tips:分支
*)并不是什么語法規定,它只是一個正則運算式,*表示任意字串,所以不管expression的值是什么,*)總能匹配成功,因此,可以沒有*)部分,如果expression沒有匹配到任何一個模式,那么就不執行任何操作,
除最后一個分支外(這個分支可以是普通分支,也可以是*)分支),其它的每個分支都必須以;;結尾,;;代表一個分支的結束,不寫的話會有語法錯誤,最后一個分支可以寫;;,也可以不寫,因為無論如何,執行到esac都會結束整個case-in陳述句,
case-in的pattern部分支持簡單的正則運算式,具體來說,可以使用以下幾種格式:
| 格式 | 說明 |
|---|---|
* |
表示任意字串, |
| [abc] | 表示 a、b、c 三個字符中的任意一個,比如,[15ZH] 表示 1、5、Z、H 四個字符中的任意一個, |
| [m-n] | 表示從 m 到 n 的任意一個字符,比如,[0-9] 表示任意一個數字,[0-9a-zA-Z] 表示字母或數字, |
| |
表示多重選擇,類似邏輯運算中的或運算,比如,abc | xyz 表示匹配字串 "abc" 或者 "xyz", |
用;;&終止每個條件塊,例如:
read -n 1 -p "Type a character > "
echo
case $REPLY in
[[:upper:]]) echo "'$REPLY' is upper case." ;;&
[[:lower:]]) echo "'$REPLY' is lower case." ;;&
[[:alpha:]]) echo "'$REPLY' is alphabetic." ;;&
[[:digit:]]) echo "'$REPLY' is a digit." ;;&
[[:graph:]]) echo "'$REPLY' is a visible character." ;;&
[[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;;&
[[:space:]]) echo "'$REPLY' is a whitespace character." ;;&
[[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;&
esac
輸出結果如下:
Type a character > a
'a' is lower case.
'a' is alphabetic.
'a' is a visible character.
'a' is a hexadecimal digit.
回圈結構
回圈結構陳述句大致分為4種:
- while
- until
- for
- select
while陳述句
當條件滿足時,while重復地執行一組陳述句,當條件不滿足時,就退出while回圈,格式如下:
while condition; do
statements
done
執行流程如下:
- 先對
condition進行判斷,如果該條件成立,就進入回圈,執while回圈體中的陳述句,也就是do和done之間的陳述句,這樣就完成了一次回圈, - 每一次執行到
done的時候都會重新判斷condition是否成立,如果成立,就進入下一次回圈,繼續執行do和done之間的陳述句,如果不成立,就結束整個while回圈,執行done后面的其它Shell代碼, - 如果一開始
condition就不成立,那么程式就不會進入回圈體,
死回圈
格式一:
while true; do
statements
done
格式二:
while [ 1 ]; do
statements
done
until陳述句
until回圈當判斷條件不成立時才進行回圈,一旦判斷條件成立,就終止回圈,
until condition; do
statements
done
until回圈的執行流程為:
- 先對
condition進行判斷,如果該條件不成立,就進入回圈,執行until回圈體中的陳述句(do和done之間的陳述句),這樣就完成了一次回圈, - 每一次執行到
done的時候都會重新判斷condition是否成立,如果不成立,就進入下一次回圈,繼續執行回圈體中的陳述句,如果成立,就結束整個until回圈,執行done后面的其它Shell代碼,
for陳述句
C語言風格的 for 回圈
格式如下:
for((exp1; exp2; exp3)); do
statements
done
exp1、exp2、exp3是三個運算式,其中exp2是判斷條件,for回圈根據exp2的結果來決定是否繼續下一次回圈;
它的運行程序為:
- 先執行
exp1, - 再執行
exp2,如果它的判斷結果是成立的,則執行回圈體中的陳述句,否則結束整個for回圈, - 執行完回圈體后再執行
exp3, - 重復執行2、3步驟,直到
exp2的判斷結果不成立,就結束回圈,
for-in回圈
格式如下:
for variable in value_list; do
statements
done
variable表示變數,value_list表示取值串列,
每次回圈都會從value_list中取出一個值賦給變數 variable,然后進入回圈體(do和done之間的部分),執行回圈體中的statements,直到取完value_list中的所有值,回圈就結束了,
value_list:
- 具體的值,例如:
for i in 1 2 3 'dd';do echo $i;done
{start..end},例如:
# 求1到10的和
sum=0
for i in {1..10}; do
sum=$((sum+i))
done
echo $sum
- 命令的執行結果,例如:
# 求100以內偶數的和
for i in $(seq 2 2 100); do
sum=$((sum+i))
done
echo $sum
- 通配符,例如:
# 列印當前路徑.log結尾的檔案
for i in *.log; do echo $i;done
Tips:若當前路徑無.log結尾的檔案,則會列印
*.log
- 特殊變數,
$*、$@等,例如:
for i in $@; do
sum=$((sum+i))
done
echo $sum
select-in陳述句
select-in回圈用來增強互動性,它可以顯示出帶編號的選單,用戶輸入不同的編號就可以選擇不同的選單,并執行不同的功能,非常適合終端(Terminal)這樣的互動場景,格式如下:
select variable in value_list; do
statements
done
variable表示變數,value_list表示取值串列,
例如:
echo "選擇你要學習的科目:"
select i in 'Linux' 'Python' 'Java' 'C++' 'PHP'; do
echo "你選擇了${i},"
done
結果如下:
選擇你要學習的科目:
1) Linux
2) Python
3) Java
4) C++
5) PHP
#? 5
你選擇了PHP,
#? 2
你選擇了Python,
#? 666
你選擇了,
Tips:
select是死回圈,輸入空值或者輸入的值無效,都不會結束回圈,只有遇到break陳述句,或者按下Ctrl+D組合鍵才能結束回圈,
例如:
echo "選擇你要學習的科目:"
select i in 'Linux' 'Python' 'Java' 'C++' 'PHP'; do
echo "你選擇了${i},"
break
done
結果如下:
選擇你要學習的科目:
1) Linux
2) Python
3) Java
4) C++
5) PHP
#? 5
你選擇了PHP,
select-in陳述句常和case-in陳述句一起使用,
break
格式如下:
break n
n表示跳出回圈的層數,如果省略n,則表示跳出當前,
continue
格式如下:
continue n
n表示回圈的層數:
- 如果省略
n,則表示continue只對當前層次的回圈陳述句有效,遇到continue會跳過本次回圈,忽略本次回圈的剩余代碼,直接進入下一次回圈, - 如果帶上
n,比如n的值為2,那么continue對內層和外層回圈陳述句都有效,不但內層會跳過本次回圈,外層也會跳過本次回圈,其效果相當于內層回圈和外層回圈同時執行了不帶n的continue,
與break的區別:
break用來結束當前整個回圈;continue用來結束本次回圈,直接跳到下一次回圈,如果回圈條件成立,還會繼續回圈;
函式
函式的本質是一段可以重復使用的腳本代碼,這段代碼被提前撰寫好了,放在了指定的位置,使用時直接調取即可,
函式定義
格式如下:
function func_name() {
statements
[return value]
}
Tips:關鍵詞
function是可選的,但必須在一個專案中保持一致,
說明:
function是Shell中的關鍵字,專門用來定義函式,可以不寫,但要求在整個專案腳本中保持一致,即統一不寫或都寫;func_name是函式名,按照約定規范,函式名后面必須帶上();statements是函式要執行的代碼,也就是一組陳述句;return value表示函式的回傳值,其中return是Shell關鍵字,專門用在函式中回傳一個值;這一部分可以寫也可以不寫,
函式呼叫
呼叫Shell函式時可以給它傳遞引數,也可以不傳遞,如果不傳遞引數,直接給出函式名字即可,格式如下:
func_name
如果傳遞引數,那么多個引數之間以空格分隔:
func_name param1 param2 param3...
Tips:不管是哪種呼叫方式,函式名字后面都不需要帶
()
函式引數
函式引數是Shell位置引數的一種,在函式內部可以使用$n來接收,例如,$1表示第一個引數,$2表示第二個引數,依次類推,
除了$n,還有另外三個比較重要的變數:
$#可以獲取傳遞的引數的個數;$@或者$*可以一次性獲取所有的引數
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/42953.html
標籤:Linux
