shell 指令碼語言是一種解釋型語言;
shell指令碼的實質是 shell命令的有序集合;
1 shell編程的基本過程
1)建立shell檔案
2)賦予可執行檔許可權 chmod a+x filename
3)執行shell檔案 ./filename
2 shell 變數
1)使用者自訂變數
命名規則通C語言的命名規則;
變數賦值的方式:先寫變數名,然後是 = ,緊接著是新值,中間不要有空格。當想取出變數的值時,加“$"符號即可
當賦值的內容中有空格時,注意請加上雙引號; 可以使用unset +變數名 可以取消變數的賦值
例如:
定義:name=value (使用帶空格的值時加引號)
訪問:$name
例:FRUIT=apple
$echo $FRUIT(結果為apple)
$echo FRUIT(結果為FRUIT)
Bourne Shell只支援標量,Korn Shell中支援數組。
數組建立: name[index]=value 數組訪問:${name[index]}
唯讀變數:readonly name
刪除變數:unset name
局部變數(只在當前SHELL執行個體中存在),環境變數(SHELL任何子進程都能使用),SHELL變數(正確運行所必需,如PWD,PATH,HOME等)。
匯出環境變數:export name
可能會見到形如 ${variable}形式的變數,變數名兩側的額外的花括弧通常用來協助識別 $ 後的變數名。
此外注意shell中的反引號的用途:
反引號 ·是在 波浪號 ~ 同一鍵位。 反引號允許你將shell 命令的輸出賦給變數,它是指令碼編程中比較重要的構件之一。
用法如: test=`date` , shell會運行反引號中的命令,並將其輸出給變數test。
下面我們舉例,在指令碼中通過反引號獲得當前日期並用他來產生唯一檔案名:
#!/bin/bash#date.shtoday=`date +%y%m%d`ls /home > log.$today
注意date命令後要有空格 `date +%y%m%d`
chmod u+x date.sh
./date.sh 此時產生了檔案log.130710
這裡用到了 重新導向輸入 > 。此外還有重新導向輸入 < , 還有 >> 表示將輸出追加到檔案的末尾。
2)位置變數
$0 :
$1,......$9分別包括第一個到第九個命令列的參數
$# 命令輸入的個數
$* $@ :所有命令列的參數
$? :前一個命令的退出狀態
$$ 包含正在執行進程的ID號
3)環境變數
4)預定義變數
3 shell程式和語句
shell程式時由 零和多條shell語句構成,shell語句包括:
說明性語句:以#開頭到本行結束;
功能性語句 :shell命令、使用者程式和其他shell程式;
結構性語句:條件測試,多路分支,迴圈語句,迴圈控制語句等等;
1)說明性語句
在shell程式的開頭加 #!/bin/sh 意思是告訴OS用那種類型的shell來解釋執行改程式
2)功能性語句
read 從標準輸入讀入一行,並賦值給後面的變數;可阻塞
數學運算:
expr 算術運算命令 主要用於進行簡單的整數運算:包括 加+、減-、乘 \* 、除/、 求模 %;
注意:
a)expr後的運算式個符號間需用空格隔開
b)expr支援的操作符有: |、&、<、<=、=、!=、>=、>、+、-、*、/、%
c)expr支援的操作符中所在使用時需用\進行轉義的有:|、&、<、<=、>=、>、*
e)expr只支援整數運算
注意變數與運算子之間要有空格,比如:: $ expr 1 + 9, 輸出結果為 10.
此外要特別注意expr命令中的一些詭異的結果,如 expr 5 * 2, 會出錯。此時我們需要使用shell的逸出字元\ 來識別容易被shell錯誤解釋
的任一字元:
$ expr 5 \* 2$ 10
注意bash shell 為了保持和Bourne shell的相容而包含了expr命令,他注意使用$ 和[ ]來實現把一個數學運算結果賦給某個變數,
如 $[ operation ] 將數學運算式圈起來:
注意:
a)$[]將中括弧內的運算式作為數學運算先計算結果再輸出
b)對$[]中的變數進行訪問時前面需要加$
c)$[] 也只支援整數運算
、
$ v1=$[1 + 5]$ echo $v1$ 6$ v2=$[$v1 * 2]$ 12
進行浮點數計算的方法:
bc是linux下的一個簡單計算機,支援浮點數計算,在命令列下輸入bc即進入計算機程式,而我們想在程式中直接進行浮點數計算時,利用一個簡單的管道即可解決問題。
注意:
1)經我測試bc支援除位操作運算子之外的所有運算子。
2)bc中要使用scale進行精度設定
3)浮點數計算執行個體
基本格式為: variable=`echo "options; ecpression" | bc` , 注意使用了反引號。
var=3.14 var=`echo "scale=2;$var*3"|bc` echo $var
輸出結果為 9.42
此外可以使用 awk 進行浮點數運算:
var=1 var=`echo "$var 1"|awk '{printf("%g",$1*$2)}'` echo $var
輸出結果為2
介紹:
awk是一種文本處理工具,同時也是一種程式設計語言,作為一種程式設計語言,awk支援多種運算,而我們可以利用awk來進行浮點數計算,和上面bc一樣,通過一個簡單的管道,我們便可在程式中直接調用awk進行浮點數計算。
注意:
1)awk支援除微操作運算子之外的所有運算子
2)awk內建有log、sqr、cos、sin等等函數
3)浮點數計算執行個體
var=3.14 var=`echo "$var 2"|awk '{printf("%g",sin($1/$2))}'` echo $var
輸出結果為1
test 可測試三種對象 :字串 整數 檔案屬性
tput 用於設定中斷的工作模式;
3)結構性語句:
條件陳述式及多路分支語句用法:
1、使用if_then語句
if command
then
commands
fi
先運行if後面的命令,如果命令的退出狀態是0(成功執行命令),就將執行then後面,fi前面的所有命令。否則就跳到fi 後面繼續執行。
2、if-then-else語句
if command
then
commands
else
commands
fi
3、嵌套if語句
if command1
then
commands
elif command2
then
commands
elif command3
then
commands
fi
4、test命令(方括弧[ ]為同義字)
用於提供對條件的判斷
if test condition 也可以不用test condition,而使用 [ conditon ] ([ , ] 的前後必須有空格)
then
commands
fi
condition有三種:
(1)數值比較: –eq, –ne, –ge,-gt, -le, lt
但是要注意:test命令無法處理儲存在變數中的浮點值。
使用bash計算機bc時,只是欺騙了shell把浮點值作為字串值儲存於一個變數中。如果只是先使用echo語句顯示結果,這種方法很好。但是在面向數值的函數(如數值測試條件)中不起作用。 底線是不能在test中使用非整數變數.
(2)字串比較:=,!=,<,>,-n(檢測字串長度是否大於0),-z(檢測字串長度是否等於0)
字串相等:測試比較將所有標點符號和大寫都考慮在內
字串順序:要注意兩點:
1)’>’,’<’一定要用’\’轉義,否則shell會將它們當做重新導向符號,將字串值看做檔案名稱
2)大於和小於的順序與在sort命令中的順序不同。
在test中,同一個字母,大寫字母>小寫字母,在sort中,相反。
字串大小:評估一個變數是否包含資料時,使用-n和-z比較方便對空變數和未初始化的變數檢測出的長度也為0
(3)檔案比較
檔案比較是shell指令碼中最強大和最常用的一類比較。test可以測試檔案狀態和路徑。(使用的非常頻繁!)
-d file: 檢查file是否存在並且是一個目錄
-e file: 檢查file是否存在
-f file: 檢查file是否存在並且是一個檔案
-r file: 檢查file是否存在並且可讀
-s file: 檢查file是否存在並且不為空白
-w file: 檢查file是否存在並且可寫
-x file: 檢查file是否存在並且可執行
-O file: 檢查file是否存在並且被目前使用者擁有
-G file:檢查file是否存在並且預設組是否為目前使用者組
file1 –nt file2: 檢查file1是否比file2新
file1 –ot file2: 檢查file1是否比file2舊
5、複合條件查詢
[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]
6、if-then的進階特徵
(1)使用雙圓括弧表示數學運算式
(( expression ))
expression包括除了標準數學操作符外的其他動作符如下:
++, --, !, ~, **, <<, >>, &, |, &&, ||
(2)使用雙方括弧表示進階字串處理函數
[[ expression ]]
提供了除test命令中的標誌字串比較以外的模式比對功能
在模式比對中,可以定義與字串值相匹配的Regex
來個if嵌套語句的例子,判斷潤年:
#!/bin/bash# This script will test if we're in a leap year or not.year=`date +%Y` #命令的結果可以直接賦值給一個變數,如果要檢查一個命令的返回狀態,就用$?if [ $[$year % 400] -eq 0 ]; then echo "This is a leap year. February has 29 days."elif [ $[$year % 4] -eq 0 ]; then if [ $[$year % 100] -ne 0 ]; then #嵌套從這裡開始 echo "This is a leap year, February has 29 days." else echo "This is not a leap year. February has 28 days." fielse echo "This is not a leap year. February has 28 days."fi
7、case 命令
可以使用case命令,而不是編寫所有的elif語句來繼續檢查相同的變數值。
case命令以列表導向檢查單個變數的多個值:
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
4)進階結構性語句:迴圈語句(for,while,until用法)
1,for迴圈使用方法(for/do/done)
A, for … in 語句
for 變數 in seq字串
do
action
done
說明:seq字串 只要用空白字元分割,每次for…in 讀取時候,就會按順序將讀到值,給前面的變數。
#!/bin/bashfor i in $(seq 10)do echo $idone
B.for((賦值;條件;運算語句))
for((賦值;條件;運算語句))
do
action
done;
#!/bin/bashfor((i=1;i<=10;i++))do echo $idone
2,while迴圈使用(while/do/done)
while 條件陳述式
do
action
done
#!/bin/bashi=12while [[ $i -gt 6 ]]do echo $i ((i--))done
3,until迴圈語句
until 條件
do
action
done
意思是:直到滿足條件,就退出。否則執行action.
#!/bin/bashi=5until [[ $i -lt 0 ]]do echo $i ((i—))done
echo -n 表示 省略語句後面的分行符號,預設是有分行符號的;下面代碼中,在列印的語句後面有 \c 表示不換行;\b表示退格 \f表示清屏;