<來源網址:http://yuxin.blog.51cto.com/addblog.php>php
Linux中的shell腳本編程:shell
shell腳本是什麼:編程
shell腳本是一個可反覆執行的可以實現一些功能的文件,通常以.sh結尾。ubuntu
Shell腳本有什麼用:vim
在工做中你可能須要常常執行一組命令以完成一些任務,若是天天都要這麼作就會變得枯燥無趣,或者這組命令須要在多臺服務器上執行,而其中又須要大量的修改某些配置文件,若是每次都手動的去執行這些命令就會極大的下降工做效率並且很容易由於粗心某個單詞寫錯形成排錯上的困難,這時候就能夠寫個shell腳原本完成以上工做,須要的時候執行一次就能夠了,還能夠把它寫到任務計劃裏邊,讓它週期性的自動執行,即提升了工做效率也下降了出錯概率。數組
Shell腳本的結構組成和執行順序:bash
在shell腳本中第一行是有特殊意義的,用來標示執行腳本的shell程序,例如:服務器
#!/bin/bash : 這表示該腳本使用/bin/bash來執行,腳本能夠由哪些shell程序來執行取決於你當前的系統支持哪些shell,能夠用 # cat /etc/shells來查看當前系統支持的shell。less
腳本中的第二行通常爲#號開頭的註釋行,用來描述腳本的做用和功能,固然若是你只是用來測試練習使用的也能夠不寫,但最好能養成一個好的習慣,在shell腳本中全部以#號開頭的行都爲註釋行,用來描述腳本的做用和提示性信息,在腳本執行過程當中是不會被執行的,但腳本開頭的第一行的第一個#號除外,它是用來標示腳本的執行shell程序的。ide
腳本中以第三行開始就是腳本的主體組成也就是要執行一個個命令了,若是你第二行的註釋信息有好多行,也可能就不是從第三行開始了,總之若是是不想讓被執行的內容該行開頭都要加上#號。
腳本的執行順序,正常狀況下讀取腳本的第一行決定調用哪一個shell程序來執行該腳本,而後開始自上而下、自左往右逐條執行每一行的每個命令,若是一行裏要執行多個命令需使用;號隔開,遇到#號則跳過該行,可是也有例外狀況,腳本中的某些關鍵字能夠改變腳本的執行順序,甚至在中斷該腳本的執行,例如,exit break while 等,下邊會作詳細介紹。
第一章、Shell腳本中的變量
有些時候在腳本的編寫過程當中你須要反覆用到同一個路徑或者同一段字符串,這時你就能夠定義一個變量,把你反覆用到的這段內容賦值給該變量,當用到的時候之須要調用該變量就能夠了。變量的賦值不只僅是固定的一段字符串,能夠是一條命令的執行結果,能夠是腳本互交輸入的內容,也能夠是與其餘變量算術運算後的結果,按變量的類型可分爲如下幾類:
環境變量:對當前shell和子shell生效,像腳本的執行就是在子shell中進行,因此在當前shell中定義的環境變量一樣能夠在shell腳本中使用,可以使用#env 命令查看當前shell中的全部環境變量,系統預約義的環境變量可直接調用。
環境變量的設置方法有三種:
1># declare -x VAR_NAME=value
2># export VAR_NAE=value
3># set VAR_NAME=value
VAR_NAME爲變量名稱該名稱爲自定義,但要遵循如下三個原則:
1.只能包含字母、數字和下劃線,而且不能以數字開頭
2.不能與關鍵字衝突 (例如if for case 等,下邊會詳細介紹)
3.最好能作到見名知意也就是起個有意義的名字
value爲變量的具體內容
# echo $VAR_NAME 來顯示變量的內容
局部變量:也叫本地變量與環境變量想對應,只對當前shell生效,shell腳本中定義的變量大部分都爲這類變量,當腳本執行結束時定義的變量也隨之消失。可以使用# set 命令查看當前shell中的全部局部變量。
局部變量的設置方法通常爲:VAR_NAME=value,一樣名稱的定義也要遵循上邊提到的定義環境變量的三個原則。
特殊變量:shell對一些參數作特殊處理,這寫參數只能被引用而不能被賦值,例如:
$? : 引用上條命令的執行結果的返回值
0 : 上條命令成功執行
1-255 :均爲執行失敗
$$ : 腳本運行的當前進程ID號
$# : 向腳本傳遞的參數個數
位置變量 :和特殊變量同樣他們只能被引用不能被賦值,若是要向腳本傳遞參數就能夠用位置變量來引用傳遞的參數,此數目能夠任意多,但只有前9個能夠被訪問,例如:
$0 : 表示腳本名稱
$1 : 表示向腳本傳遞的第一個參數
$2 : 表示向腳本傳遞的第二個參數
$3 …
.
.
$9 : 表示向腳本傳遞的第九個參數
變量引用:上面講述了四種類型的變量,如何引用本身定義的變量呢其實很簡單,環境變量和局部變量只須要在變量名前加$符號就能夠了,例如:
# export COS=ubuntu //定義環境變量COS賦值爲ubuntu
# echo $COS //使用echo 命令回顯變量COS
ubuntu //變量的值
變量自身也能夠引用其餘變量,例如:
# VAR=」$COS is good.」 //定義局部變量VAR賦值爲$COS is good.
# echo $VAR //使用echo命令回顯變量VAR
ubuntu is good. //變量VAR的值
上邊例子能夠看出變量VAR賦值時引用了變量COS的值,但要注意若是在給變量賦值時引用了其餘變量須要用」「雙引號把整個內容括起來,否則是不會作變量替換,以下:
# VAR='$COS is good.'
# echo $VAR
$COS is good.
能夠看到$COS並無作變量替換,仍是顯示爲$COS
變量的賦值還能夠引用其餘命令的執行結果,例如:
# VAR=`pwd`
# echo $VAR
/root
上邊這個例子中變量VAR的賦值引用了命令pwd的執行結果,同時也要注意若是引用的是命令的執行結果則須要把這個命令用``反引號括起來。
第二章、if條件判斷語句
有些時候在shell腳本的執行過程當中可能發生各類意外狀況,例如,你想寫個腳原本建立幾個空目錄,當腳本執行完畢時發現有些目錄並非空的,由於這個目錄以前就已經存在了,而你再執行mkdir命令時並不能執行成功,或者你想讓腳本執行成功或失敗時可以echo一句話再結束腳本,而不是默不做聲腳本萬一沒有執行成功也沒法察覺,這時都須要用到if條件判斷,if語句可分爲單分支、雙分支和多分支三個類型。
單分支if語法格式:
if 條件 ; then
命令1
命令2 …
fi
示例:
# vim test.sh
#!/bin/bash
# test if
if pwd ; then
echo It is good.
fi
該腳本的意思是:若是pwd命令執行成功則顯示一句話It is good,若是不成功
則結束腳本,執行結果以下:
# bash test.sh
/root
It is good.
雙分支if語法格式:
if 條件;then
命令...
else
命令...
fi
示例:
# vim test.sh
#!/bin/bash
# test if
if lss ; then
echo command success.
else
echo command failed.
fi
該腳本的意思是:若是lss這個命令執行成功則顯示command success,不然顯示command failed,執行結果以下:
# bash test.sh
test.sh: line 3: lss: command not found
command failed
能夠看到由於lss命令執行失敗,顯示command failed,若是不想顯示命令的執行結果只是用來作條件來判斷是能夠用 &> /dev/null 進行輸出重定向。
多分支if語句語法格式:
if 條件一 ; then
命令...
elif 條件二 ; then
命令...
else
命令...
fi
示例:
# vim test.sh
#!/bin/bash
# test if
if lss &> /dev/null ; then
echo less success.
elif ls &> /dev/null ;then
echo ls success.
else
echo all error.
fi
該腳本的意思是:若是lss命令執行成功顯示 lss success,若是lss命令沒有執行成功則判斷ls 命令執行是否完成,成功則顯示ls success,不然顯示 all error,執行結果以下:
# bash test.sh
ls success.
以上示例都是用命令執行是否成功來作條件的判斷的,其實也能夠用條件測試的結果的來判斷,例如判斷變量COS的值是否爲空,或者是否與變量VAR的值是否相同等,條件測試後邊會作詳細介紹,另外if語句中也能夠在嵌套if語句,進行二次判斷,使用格式相同,從上邊的例子也能夠看出if語句只要知足任何一個條見就退出整個語句,再也不進行其餘條件的判斷。
第三章、shell中的條件測試算術運算
shell中使用條件測試和算術運算可使腳本更加智能,可以判斷命令是否執行成功也能夠用來測試兩個變量的數值是否相等,也能夠來判斷兩個字符串是否一致,條件測試大體可分爲三類,其基本語法格式以下:
[ 條件 ] 或者 [[ 條件 ]]
整數測試:可以使用的選項有:
-eq
等於
-gt
大於
-ge
不大於
-ne
不等於
-lt
小於
-le
不小於
示例:
# vim test.sh
#!/bin/bash
# test
COS=1
if [ $COS -eq 1 ] ;then
echo success.
else
echo failed.
fi
執行結果爲:
# bash test.sh
success.
由於變量COS的值等於1,因此執行echo success.
字符串測試:可以使用的選項有:
=
等於
>
大於
>=
大於等於
!=
不等於
<
小於
<=
小於等於
示例:
# vim test.sh
#!/bin/bash
# test
VAR=ubuntu
if [ $VAR = ubuntu ] ; then
echo good.
fi
腳本執行結果:
# bash test.sh
good.
若是變量中存在空格或單引號須要用雙引號把他們括起來。
文件測試:可以使用的選項有:
-e
測試文件是否存在
-s
是否存在並不爲空
-f
是不是文件
-d
是不是目錄
-r
是否有讀權限
-w
是否有寫權限
-x
是否有執行權限
-n t
那個文件更新
示例:
# vim test.sh
#!/bin/bash
# test
if [ -x /etc/passwd ] ;then
echo good.
else
echo bad.
fi
執行結果:
# bash test.sh
bad.
由於對/etc/passwd文件沒有執行權限因此執行echo bad.。
算術運算:可用的選項有:
+
加
-
減
*
乘
/
除
%
取餘
語法格式:
$[運算表達式] 或者
$((運算表達式))
示例:
# VAR=$[2+3]
# echo $VAR
5
第四章、case條件判斷語
當if條件判斷語句作某寫字符串測試時,須要編寫大量陳長的語句來實現,例如,指定一個變量,若是變量的值爲A則顯示first line,若是變量的值爲B則顯示second line,若是變量值爲C則顯示third line,用if條件判斷語句:
示例:
# vim test.sh
#!/bin/bash
# test
COS=B
if [ $COS = A ];then
echo first line
elif [ $COS = B ]; then
echo second line
elif [ $COS = C ]; then
echo third line
fi
執行結果:
# bash test.sh
second line
若是用case條件判斷語句則能夠大大簡化須要編寫的內容
case語法格式:
case 變量 in
字符串1)
命令... ;;
字符串2)
命令... ;;
字符串3)
命令... ;;
…
esac
示例:
# vim test.sh
#!/bin/bash
# test case
COS=B
case $COS in
A)
echo first line ;;
B)
echo second line ;;
C)
echo third line ;;
esac
執行結果:
# bash test.sh
second line
從以上對比能夠看出,若是是字符串測試case語句要比if語句簡化了不少,並且條理很是明晰。
第五章、for循環語句
循環顧名思義會循環執行直到知足必定條件退出循環,for循環爲遍歷列表循環,列表便可以是定義的一個數組也能夠是一個命令的執行結果也能夠是一個變量,for循環會逐個匹配列表中每一個字符串,默認是以空格和換行符爲分割點,因此若是你給出的列表中存在一個字符串包含有空格的話,for循環會把他拆開做爲兩個值。
For循環語法格式:
for 變量 in 列表;do
命令...
done
示例:
# vim test.sh
#!/bin/bash
# test for
for I in {1..5}; do
echo $I
done
該腳本的意思是:若是變量I在數組{1..5}中,執行顯示變量I,第一次循環I=1,執行echo $I 也就是顯示1,第二次循環I=2,執行echo $I 也就是顯示2,以此類推...直到I=5時,遍歷完數組中的全部數值,顯示5,而後結束for循環,腳本執行結果以下:
# bash test.sh
1
2
3
4
5
for循環會以空格分隔列表中每一個值,若是數據值中有空格,或者包含有單引號,則必須使用雙引號括起來,例如:
# vim test.sh
#!/bin/bash
# test for
for I in a ab a b a'b' ;do
echo $I
done
執行結果爲:
# bash test.sh
a
ab
a
b
ab
這並非咱們想要的結果,須要用下面的方法:
# vim test.sh
#!/bin/bash
# test for
for I in a ab 「a b」 「a'b'」 ;do
echo $I
done
執行結果爲:
# bash test.sh
a
ab
a b
a'b'
這纔是咱們想要的結果。
第六章、while、until循環語句、break和 continue
while循環語句可讓知足某條件的狀況下反覆執行while循環中的命令,當條件不知足時自動退出循環,繼續按順序執行腳本中的其餘內容,其基本語法格式以下:
while循環語法格式:
while 條件 ; do
命令...
done
示例:
# vim test.sh
#!/bin/bash
# test while
declare -i COS=0
while [ $COS -lt 5 ] ; do
echo $COS
let COS++
done
腳本的意思是:定義整型變量COS並賦值爲0,若是COS的值小於5,則顯示COS的值並let COS++ 讓COS的值自動加1,執行結果以下:
# bash test.sh
0
1
2
3
4
可見當COS的值變成5時不知足條件,則退出while循環,結束腳本。
break能夠中斷循環,和if語句配合使用,在while循環中知足if語句的條件時退出while循環,還用剛纔的腳原本試試break的做用。
示例:
# vim test.sh
#!/bin/bash
# test break
declare -i COS=0
while [ $COS -lt 5 ];do
if [ $COS -eq 3 ]; then
break
fi
echo $COS
let COS++
done
與上邊的例子不一樣的地方在於此次在循環中增長了if條件判斷,若是COS的值等於3時執行break,看看什麼效果:
# bash test.sh
0
1
2
當COS的值爲3時執行了break退出了while循環。
continue能夠提早中斷此次循環,進入下一次循環,與break不一樣的地方在於break是直接退出循環,而continue是中斷該次循環進入下一次循環,繼續用剛纔的例子看下和break有什麼不一樣。
示例:
# vim test.sh
#!/bin/bash
# test continue
declare -i COS=0
while [ $COS -lt 5 ]; do
if [ $COS -eq 3 ]; then
let COS++
continue
fi
echo $COS
let COS++
done
執行結果:
# bash test.sh
0
1
2
4
因爲COS=3時執行了continue,因此沒有顯示3,這就是continue的做用。
Until 循環是直到條件知足時才退出循環,與while循環正好相反,語法格式與while同樣。
示例:
# vim test.sh
#!/bin/bash
# test until
declare -i COS=0
until [ $COS -eq 5 ] ;do
echo $COS
done
執行結果:
# bash test.sh
0
1
2
3
4
從腳本的執行結果能夠看出,當until的條件也就是COS=5時,退出了循環。
第七章、函數
shell腳本中的函數與變量有點相似,都是能夠定義一個名字等使用時直接調用就能夠了,可是變量只能進行簡單的字符串或者命令的賦值,而函數能夠執行更復雜的命令,甚至能夠說是腳本中的腳本,其基本語法格式以下:
函數語法格式:
function 名字 {
命令...
}
或者
名字() {
命令...
}
示例:
# vim test.sh
#!/bin/bash
# test function
FUN() {
COS=`date +%F`
echo 「Today is $COS.」
}
echo Hello
FUN
執行結果:
# bash test.sh
Hello
Today is 2012-06-19.
函數自己並不會被執行,只有在調用時纔會執行。