上節回顧
在上一篇博文中,主要介紹了Shell腳本編程的背景,怎樣創建人生中第一個Shell腳本以及Shell變量等內容。接下來將接着介紹介紹Shell編程,主要是圍繞着Shell運算、流程控制語句、自定義函數以及腳本調試等方面展開。
運算符
例:
num1=11
num2=22
sum=$num1+$num2
echo $sum
格式 :expr m + n 或$((m+n)) 注意expr運算符間要有空格
expr命令:對整數型變量進行算術運算 (注意:運算符前后必須要有空格)
expr 3 + 5
expr 3 – 5
echo `expr 10 / 3`
10/3的結果為3,因為是取整
expr 3 \* 10 # \ 是轉義符
例:計算(2 +3 )×4 的值
1 .分步計算
S=`expr 2 + 3`
expr $S \* 4
2.一步完成計算
expr `expr 2 + 3` \* 4
S=`expr \`expr 2 + 3\` \* 4`
echo $S
或
echo $(((2 + 3) * 4))
$()與${}的區別
$( )的用途和反引號``一樣,用來表示優先執行的命令
eg:echo $(ls a.txt)
${ } 就是取變量了 eg:echo ${PATH}
$((運算內容)) 適用於數值運算
eg: echo $((3+1*4))
內置test命令
內置test命令常用操作符號[]表示,將表達式寫在[]中,如下:
[ expression ]
或者:
test expression
注意:expression首尾都有個空格
eg: [ ] ;echo $?
測試范圍:整數、字符串、文件
表達式的結果為真,則test的返回值為0,否則為非0。當表達式的結果為真時,則變量$?的值就為0,否則為非0
字符串測試:
test str1 == str2 測試字符串是否相等
test str1 != str2 測試字符串是否不相等
test str1 測試字符串是否不為空,不為空,true,false
test -n str1 測試字符串是否不為空
test -z str1 測試字符串是否為空
eg:
name=linzhiling
[ “$name” ] && echo ok
; 命令連接符號
&& 邏輯與 條件滿足,才執行后面的語句
[ -z “$name” ] && echo invalid || echo ok
|| 邏輯或,條件不滿足,才執行后面的語句
test “$name” == ”yangmi” && echo ok || echo invalid
整數測試:
test int1 -eq int2 測試整數是否相等 equals
test int1 -ge int2 測試int1是否>=int2
test int1 -gt int2 測試int1是否>int2
test int1 -le int2 測試int1是否<=int2
test int1 -lt int2 測試int1是否<int2
test int1 -ne int2 測試整數是否不相等
eg:
test 100 –gt 100
test 100 –ge 100
如下示例兩個變量值的大小比較:
-gt表示greater than大於的意思,-le表示less equal表示小於等於。
文件測試:
test -d file 指定文件是否目錄
test –e file 文件是否存在 exists
test -f file 指定文件是否常規文件
test –L File 文件存在並且是一個符號鏈接
test -r file 指定文件是否可讀
test -w file 指定文件是否可寫
test -x file 指定文件是否可執行
eg:
test -d install.log
test –r install.log
test –f xx.log ; echo $?
[ -L service.soft ] && echo “is a link”
test -L /bin/sh ;echo $?
[ -f /root ] && echo “yes” || echo “no”
多重條件測試:
條件1 –a 條件2 邏輯與 兩個都成立,則為真
條件1 –o 條件2 邏輯或 只要有一個為真,則為真
! 條件 邏輯非 取反
eg:
num=520
[ -n “$num” –a “$num” –ge 520 ] && echo “marry you” || echo “go on”
age=20
pathname=outlog
[ ! -d“$ pathname”] && echo usable || echo used
流程控制語句
if/else命令
1, 單分支if條件語句
if [ 條件判斷式 ]
then
程序
fi
或者
if [ 條件判斷式 ] ; then
程序
fi
eg:#!/bin/sh
if [ -x /etc/rc.d/init.d/httpd ]
then
/etc/rc.d/init.d/httpd restart
fi
單分支條件語句需要注意幾個點:
if語句使用fi結尾,和一般語言使用大括號結尾不同。
[ 條件判斷式 ] 就是使用test命令判斷,所以中括號和條件判斷式之間必須有空格
then后面跟符號條件之后執行的程序,可以放在[]之后,用“;”分割,也可以換行寫入,就不需要";"了。
2,多分支if條件語句
if [ 條件判斷式1 ]
then
當條件判斷式1成立時,執行程序1
elif [ 條件判斷式2 ]
then
當條件判斷式2成立時,執行程序2
...省略更多條件
else
當所有條件都不成立時,最后執行此程序
fi
示例:
read -p "please input your name: " NAME
eg:
#!/bin/bash
read -p "please input your name:" NAME
#echo $NAME
if [ “$NAME” == root ]
then
echo "hello ${NAME}, welcome !"
elif [ $NAME == tom ]
then
echo "hello ${NAME}, welcome !"
else
echo "SB, get out here !"
fi
case命令
case命令是一個多分支的if/else命令,case變量的值用來匹配value1,value2,value3等等。匹配到后則執行跟在后面的命令直到遇到雙分號為止(;;)case命令以esac作為終止符。
格式
CMD=$1
case $CMD in
start)
echo "starting"
;;
Stop)
echo "stoping"
;;
*)
echo "Usage: {start|stop} “
esac
for循環
for循環命令用來在一個列表條目中執行有限次數的命令。比如,你可能會在一個姓名列表或文件列表中循環執行同個命令。for命令后緊跟一個自定義變量、一個關鍵字in和一個字符串列表(可以是變量)。第一次執行for循環時,字符串列表中的第一個字符串會賦值給自定義變量,然后執行循環命令,直到遇到done語句;第二次執行for循環時,會右推字符串列表中的第二個字符串給自定義變量,依次類推,直到字符串列表遍歷完。
第一種:
for N in 1 2 3
do
echo $N
done
或
for N in 1 2 3; do echo $N; done
或
for N in {1..3}; do echo $N; done
第二種:
for ((i = 0; i <= 5; i++))
do
echo "welcome $i times"
done
或
for ((i = 0; i <= 5; i++)); do echo "welcome $i times"; done
while循環
while命令根據緊跟其后的命令(command)來判斷是否執行while循環,當command執行后的返回值(exit status)為0時,則執行while循環語句塊,直到遇到done語句,然后再返回到while命令,判斷command的返回值,當得打返回值為非0時,則終止while循環。
第一種
while expression
do
command
…
done
練習:求1-10 各個數的平方和
第二種:
自定義函數
函數代表着一個或一組命令的集合,表示一個功能模塊,常用於模塊化編程。
以下是關於函數的一些重要說明:
在shell中,函數必須先定義,再調用
使用return value來獲取函數的返回值
函數在當前shell中執行,可以使用腳本中的變量。
函數的格式如下:
函數名()
{
命令1…..
命令2….
return 返回值變量
}
[ function ] funname [()]
{
action;
[return int;]
}
function start() / function start / start()
eg.
注意:
如果函數名后沒有(),在函數名和{ 之間,必須要有空格以示區分。函數返回值,只能通過$? 系統變量獲得,可以顯示加:return 返回值,如果不加,將以最后一條命令運行結果,作為返回值。 return后跟數值n(0-255)
腳本調試
sh -x script
這將執行該腳本並顯示所有變量的值。
在shell腳本里添加
set -x 對部分腳本調試
sh -n script
不執行腳本只是檢查語法的模式,將返回所有語法錯誤。
sh –v script
執行並顯示腳本內容。