Shell指令碼程式設計詳解
第12章 Shell指令碼程式設計
lShell命令列的執行
l編寫、修改許可權和執行Shell程式的步驟
l在Shell程式中使用引數和變數
l表示式比較、迴圈結構語句和條件結構語句
l在Shell程式中使用函式和呼叫其他Shell程式
uShell命令列的書寫規則
對Shell命令列基本功能的理解有助於編寫更好的Shell程式,在執行Shell命令時多個命令可以在一個命令列上執行,但此時要使用分號(;)分隔命令,例如:
[root@localhostroot]# ls a* -l;free;df
長Shell命令列可以使用反斜線字元(\)在命令列上擴充,例如:
[root@localhostroot]# echo “this is \
>long command”
This is long command
注意:
“>”符號是自動產生的,而不是輸入的。
12-2編寫/修改許可權及執行Shell程式的步驟
u編寫Shell程式
u執行Shell程式
Shell程式有很多類似C語言和其他程式設計語言的特徵,但是又沒有程式語言那樣複雜。Shell程式是指放在一個檔案中的一系列Linux命令和實用程式。在執行的時候,通過Linux作業系統一個接一個地解釋和執行每條命令。首先,來編寫第一個Shell程式,從中學習Shell
12-2-1編輯Shell程式
編輯一個內容如下的源程式,儲存檔名為date,可將其存放在目錄/bin下。
[root@localhostbin]#vi date
#! /bin/sh
echo “Mr.$USER,Today is:”
echo &date “+%B%d%A”
echo “Wish you a lucky day !”
注意:
#! /bin/sh通知採用Bash解釋。如果在echo語句中執行Shell命令date,則需要在date命令前加符號“&”,其中%B%d%A為輸入格式控制符。
12-2-2建立可執行程式
編輯完該檔案之後不能立即執行該檔案,需給檔案設定可執行程式許可權。使用如下命令。
[root@localhostbin]#chmod +x date
12-2-3執行Shell程式
執行Shell程式有下面三種方法:
方法一:
[root@localhostbin]#./ date
Mr.root,Today is:
二月 06 星期二
Wish you a lucky day !
方法二:
另一種執行date的方法就是把它作為一個引數傳遞給Shell命令:
[root@localhostbin]# Bash date
Mr.root,Today is:
二月 06 星期二
Wish you a lucky day !
方法三:
為了在任何目錄都可以編譯和執行Shell所編寫的程式,即把/bin的這個目錄新增到整個環境變數中。
具體操作如下:
[root@localhostroot]#export PATH=/bin:$PATH
[root@localhostbin]# date
Mr.root,Today is:
二月 06 星期二
Wish you a lucky day !
例項 12-1:編寫一個Shell程式mkf,此程式的功能是:顯示root下的檔案資訊,然後建立一個kk的資料夾,在此資料夾下建立一個檔案aa,修改此檔案的許可權為可執行。
分析:此Shell程式中需要依次執行下列命令為:
進入root目錄:cd /root
顯示root目錄下的檔案資訊:ls –l
新建資料夾kk: mkdir kk
進入root/kk目錄:cd kk
新建一個檔案aa:vi aa#編輯完成後需手工儲存
修改aa檔案的許可權為可執行:chmod +x aa
回到root目錄:cd /root
因此該Shell程式只是以上命令的順序集合,假定程式名為mkf
[root@localhostroot]#vi mkf
cd /root
ls –l
mkdir kk
cd kk
vi aa
chmod +x aa
cd /root
12-3在Shell程式中使用的引數
u位置引數
u內部引數
如同ls命令可以接受目錄等作為它的引數一樣,在Shell程式設計時同樣可以使用引數。Shell程式中的引數分為位置引數和內部引數等。
12-3-1位置引數
由系統提供的引數稱為位置引數。位置引數的值可以用$N得到,N是一個數字,如果為1,即$1。類似C語言中的陣列,Linux會把輸入的命令字串分段並給每段進行標號,標號從0開始。第0號為程式名字,從1開始就表示傳遞給程式的引數。如$0表示程式的名字,$1表示傳遞給程式的第一個引數,以此類推。
12-3-2內部引數
上述過程中的$0是一個內部變數,它是必須的,而$1則可有可無,最常用的內部變數有$0、$#、$?、$*,它們的含義如下。
l$0:命令含命令所在的路徑。
l$#:傳遞給程式的總的引數數目。
l$?:Shell程式在Shell中退出的情況,正常退出返回0,反之為非0值。
l$*:傳遞給程式的所有引數組成的字串。
例項 12-2:編寫一個Shell程式,用於描述Shell程式中的位置引數為:$0、$#、$?、$*,程式名為test1,程式碼如下:
[root@localhostbin]#vi test1
#! /bin/sh
echo “Program name is $0”;
echo “There are totally $# parameters passed to this program”;
echo “The last is $?”;
echo “The parameter are $*”;
執行後的結果如下:
[root@localhostbin]# test1 this is a test program//傳遞5個引數
Program name is /bin/test1//給出程式的完整路徑和名字
There are totally 5 parameters passed to this program//引數的總數
The last is 0//程式執行效果
The parameters are this is a test program//返回由引數組成的字串
注意:命令不計算在引數內。
例項 12-3:利用內部變數和位置引數編寫一個名為test2的簡單刪除程式,如刪除的檔名為a,則在終端中輸入的命令為:test a
分析:除命令外至少還有一個位置引數,即$#不能為0,刪除不能為$1,程式設計過程如下。
(1)用vi編輯程式
[root@localhostbin]#vi test2
#! /bin/sh
if test $# -eq 0
then
echo “Please specify a file!”
else
gzip $1//現對檔案進行壓縮
mv $1.gz $HOME/dustbin//移動到回收站
echo “File $1 is deleted !”
fi
(2)設定許可權
[root@localhostbin]#chmod +x test2
(3)執行
[root@localhostbin]# test2 a (如果a檔案在bin目錄下存在)
File a is deleted!
12-4在Shell程式中的使用變數
u變數的賦值
u變數的訪問
u變數的輸入
12-4-1變數的賦值
在Shell程式設計中,所有的變數名都由字串組成,並且不需要對變數進行宣告。要賦值給一個變數,其格式如下:
變數名=值
注意:
等號(=)前後沒有空格
例如:
x=6
a=”How are you ”
表示把6賦值給變數x,字串“How are you ”賦值給變數a。
12-4-2訪問變數值
如果要訪問變數值,可以在變數前面加一個美元符號“$”,例如:
[root@localhostbin]#a=”How are you ”
[root@localhostbin]#echo “He juest said:$a”
A is:hello world
一個變數給另一個變數賦值可以寫成:
變數2=$變數1
例如:
x=$i
i++可以寫成:
i=$i+1
12-4-3鍵盤讀入變數值
在Shell程式設計中,變數的值可以作為字串從鍵盤讀入,其格式為:
read 變數
例如:
[root@localhostbin]#read str
read為讀入命令,它表示從鍵盤讀入字串到str。
例項 12-4:編寫一個Shell程式test3,程式執行時從鍵盤讀入一個目錄名,然後顯示這個目錄下所有檔案的資訊。
分析:
存放目錄的變數為DIRECTORY,其讀入語句為:
read DIRECTORY
顯示檔案的資訊命令為:ls –a
[root@localhostbin]#vi test3
#! /bin/sh
echo “please input name of directory”
read DIRECTORY
cd $DIRECTORY
ls –l
(2)設定許可權
[root@localhostbin]#chmod +x test3
(3)執行
[root@localhostbin]#./test3
注意:
輸入路徑時需“/”
例項 12-5:執行程式test4,從鍵盤讀入x、y的值,然後做加法運算,最後輸出結果。
(1)用vi編輯程式
[root@localhostbin]#vi test4
#! /bin/sh
echo “please input x y”
read x,y
z=`expr $x+$y`
echo “The sum is $z”
(2)設定許可權
[root@localhostbin]#chmod +x test4
(3)執行
[root@localhostbin]#./ test4
45 78
The sum is 123
注意:
表示式total=`expr $total +$num`及num=`expr $num +1`中的符號“`”為鍵盤左上角的“`”鍵。
12-5表示式的比較
u字串操作符
u邏輯運算子
u用test比較的運算子
u數字比較符
u檔案操作符
在Shell程式中,通常使用表示式比較來完成邏輯任務。表示式所代表的操作符有字元操作符、數字操作符、邏輯操作符、以及檔案操作符。其中檔案操作符是一種Shell所獨特的操作符。因為Shell裡的變數都是字串,為了達到對檔案進行操作的目的,於是才提供了檔案操作符。
12-5-1字串比較
作用:測試字串是否相等、長度是否為零,字串是否為NULL。
常用的字串操作符如表12-1所示.。
表12-1常用的字串操作符
字串操作符 |
含義及返回值 |
= |
比較兩個字串是否相同,相同則為“真” |
!= |
比較兩個字串是否不相同,不同則為“真” |
-n |
比較兩個字串長度是否大於零,若大於零則為“真” |
-z |
比較兩個字串長度是否等於零,若等於零則為“真” |
例項 12-6:從鍵盤輸入兩個字串,判斷這兩個字串是否相等,如相等輸出。
(1)用vi編輯程式
[root@localhostbin]#vi test5
#! /bin/Bash
read ar1
read ar2
[ “$ar1” = “$ar2” ]
echo $? #?儲存前一個命令的返回碼
(2)設定許可權
[root@localhostbin]#chmod +x test5
(3)執行
[root@localhostroot]#./ test5
aaa
bbb
1
注意:
”[”後面和”]”前面及等號“=“的前後都應有一個空格;注意這裡是程式的退出情況,如果ar1和ar2的字串是不想等的非正常退出,輸出結果為1。
例項 12-7: 比較字串長度是否大於零
(1)用vi編輯程式
[root@localhostbin]#vi test6
#! /bin/Bash
read ar
[-n “$ar” ]
echo $? //儲存前一個命令的返回碼
(2)設定許可權
[root@localhostbin]#chmod +x test6
(3)執行
[root@localhostbin]#./ test6
0
注意:
執行結果1表示ar的小於等於零,0表示ar的長度大於零。
12-5-2數字比較
在Bash Shell程式設計中的關係運算有別於其他程式語言,用表12-2中的運算子用test語句表示大小的比較。
表12-2用test比較的運算子
運算子號 |
含義 |
-eq |
相等 |
-ge |
大於等於 |
-le |
小於等於 |
-ne |
不等於 |
-gt |
大於 |
-lt |
小於 |