




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、2020/9/26,1,第四章Shell基礎(chǔ)與編程技術(shù),4.1 SHELL概述 4.2 SHELL程序設(shè)計基礎(chǔ) 4.3 SHELL基本命令 4.4 SHELL變量 4.5 SHELL程序流程 4.6 程序調(diào)試 4.7 SHELL編程綜合范例 4.8 實戰(zhàn)技巧 系統(tǒng)資源查看與多命令執(zhí)行,2020/9/26,2,4.1 shell概述,Shell是最基礎(chǔ)和實用的linux工具,熟練掌握shell技巧及其使用方法,是用好linux的關(guān)鍵。用戶對shell的熟練程度直接體現(xiàn)用戶的linux編程水平。本章先了解shell,進而掌握shell命令、變量和程序控制結(jié)構(gòu)、程序調(diào)試,最后通過理解綜合范例,把握編
2、程技巧,達到學(xué)以致用的目的。 shell是一個工具程序,在用戶登錄后由系統(tǒng)啟動,解釋并運行由命令行或腳本文件輸入的命令,實現(xiàn)用戶與內(nèi)核間的交互。 Shell提供的變量、賦值語句、控制流等基本操作語句與高級語言中的函數(shù)調(diào)用極為相似,除了關(guān)鍵字與語法規(guī)則不同外,還有兩點不同。一是參數(shù)可以為任意字符串,多數(shù)情況下字符串不用引號;二是參數(shù)表不用括號,各參數(shù)之間也不用逗號分隔。,2020/9/26,3,Linux系統(tǒng)提供了多種不同的shell。常用的有Bourne shell(簡稱sh)、C-shelll(簡稱csh)、Korn shell(簡稱ksh)和Bourne Again shell (簡稱ba
3、sh)。它們的淵源和區(qū)別,請讀者自己到網(wǎng)上遨游一下,便略知一二。 目前l(fā)inux系統(tǒng)的缺省shell分別是Bourne Again shell,即bash。 要知道所用的linux有哪些版本的shell,可以查看/etc/shell目錄下的文件。查看命令行如下: $ cat /etc/shells 還可以用下面的命令來查看當(dāng)前的shell類型: #echo $SHELL 其中的“$SHELL”是環(huán)境變量,記錄使用的shell型。可以用$exit命令退出當(dāng)前shell。,2020/9/26,4,4.2 shell程序設(shè)計基礎(chǔ),shell擅長系統(tǒng)管理,shell腳本實質(zhì)是命令批處理。復(fù)雜腳本一般包
4、括判斷、循環(huán)、文件測試等程序結(jié)構(gòu)。這時應(yīng)對linux工具集有一些理解。工具grep、sed和awk等,在處理命令輸出和文件時功能很強大。建立shell腳本的步驟同建立文本文件相同。用vi等進行程序錄入和編輯,也可以用cat和管道等命令直接建立一個腳本文件。 【例】4.1 建立一個shell腳本,在提示符后輸入顯示和重定向命令: $ cat myprogram 回車后直接輸入命令,再回車并輸入命令,如下所示: #!/bin/sh #filename:myprogram x=”hello world.” echo $x y=”my first shell program.” echo $y exi
5、t 完成編輯按住Ctrl+Z退出,則myprogram的shell腳本程序就完成了,返回shell命令狀態(tài)。,2020/9/26,5,2020/9/26,6,同其他語言一樣,也可以通過使用任意一種文字編輯器,比如nedit、kedit、emacs、vi等來編寫shell程序。程序最好以“#!/bin/sh”為開始的第一行。符號#!用來告訴系統(tǒng)它后面的參數(shù)是用來執(zhí)行該文件的程序。在這個例子中使用/bin/sh來執(zhí)行程序。當(dāng)腳本編好后,要執(zhí)行該腳本還要改變其文件為可執(zhí)行文件屬性。但在cygwin的linux模擬環(huán)境中可以直接執(zhí)行而無需改變其文件屬性。 改變腳本文件成為可執(zhí)行文件屬性的命令行的寫法是
6、: $chmod +x myprogram 或 $chmod 755 myprogram 最后,執(zhí)行該程序的命令行寫法是: $./myprogram 或 $ bash myprogram 回車就可以看到程序的執(zhí)行結(jié)果: hello world. my first shell program.,2020/9/26,7,在shell編程時,以#開頭的句子表示這一行為注釋。 Shell對用戶輸入的命令即文件名進行分析。如果文件標記為可執(zhí)行,但不是編譯過的程序,shell把它看作shell腳本,并解釋執(zhí)行。 用戶開發(fā)的shell腳本可以駐留在命令搜索路徑的目錄之下如/bin、 /usr/bin等,像普
7、通命令一樣使用。通過這樣方式可以擴充新命令。 shell腳本經(jīng)常被用來執(zhí)行重復(fù)性的工作。當(dāng)進入系統(tǒng)時要查看有無信件、現(xiàn)有用戶群、將工作目錄改為指定目錄、顯示當(dāng)前日期等。完成這些工作的命令是固定的,可把它們寫入一個shell腳本中,每次批處理完成。 有些固定工作的命令很復(fù)雜,如文件系統(tǒng)安裝mount帶多個選項和參數(shù),此時用shell腳本存放該命令,就能提高效率。 shell的基本功能有運行程序、輸入輸出重定向、變量和文件名的替換、管道、編程與環(huán)境的控制等。 RedHat Linux帶有不少快捷方式。就是home目錄的簡寫形式。如想把一個名為sometext的文件復(fù)制到home目錄下的docs子目
8、錄中,可以用#cp sometext /docs實現(xiàn)。另外,$cd回車可隨時回到home目錄。,2020/9/26,8,(1)bash 配置文件,在用戶的home目錄下,運行命令: $ls .bash* 將會看到這些文件: .bash_history :記錄了用戶以前輸入的命令。 .bash_logout :當(dāng)用戶退出shell 時,要執(zhí)行的命令。 .bash_profile :當(dāng)用戶登入shell 時,要執(zhí)行的命令。 .bashrc :每次打開新的shell 時,要執(zhí)行的命令。 其中.bash_profile只在會話開始時讀取一次,而.bashrc每次打開新終端時都被讀一次。.bash_pr
9、ofile經(jīng)常設(shè)置先讀.bashrc文件,用戶能把所有配置都放進.bashrc里。 這些是用戶個人設(shè)置,系統(tǒng)級設(shè)置在/etc/profile、/etc/bashrc及目錄/etc/profile.d下的文件里。當(dāng)系統(tǒng)與用戶設(shè)置發(fā)生沖突時,用戶設(shè)置有效。,2020/9/26,9,(2)提示符,每打開一個控制臺console或xterm時,先看到提示符。默認提示符將顯示用戶名、主機名(默認localhost)、當(dāng)前目錄( 表示home目錄),最后一個字符是普通用戶($)或是root(#)的標記。用戶通過$PS1設(shè)置提示符。 命令:echo $PS1將顯示當(dāng)前的設(shè)定。默認設(shè)定提示符顯示的只是當(dāng)前目錄
10、的最后部分??梢杂胮wd(輸出當(dāng)前目錄,print working directory)查看細節(jié)。 怎樣讓shell自動告訴用戶的當(dāng)前目錄呢? 提示符等信息一般包含在文件/etc/bashrc中,用戶可以通過編輯各自home目錄下的.bash_profile和.bashrc來改變設(shè)置。 在man bash中的PROMPTING部分,對這些參數(shù)有詳細說明。用戶可以自行設(shè)置內(nèi)容如時間、命令歷史記錄號或不同顏色等。 在/.bashrc中,用戶比較清晰的設(shè)定是:PS1=0331mw0330m root在/.bashrc中的設(shè)定是:PS1=0330;31mw0330m 這時用戶得到的提示符是:/usr/
11、bin 當(dāng)用root時,變成:/usr/bin 用戶已去掉了主機名和用戶名。普通用戶提示符可以是黑底白字或白底黑字。,2020/9/26,10,(3)改變 $PATH,$PATH與$PS1都是環(huán)境變量。輸入set將列出所有當(dāng)前定義的環(huán)境變量。用戶看到的環(huán)境變量在shell配置文件中的定義,可能是用戶自己的配置文件,也可能是由root通過/etc下面的系統(tǒng)級文件定義的。如果用戶使用X,更多的變量將由X和用戶窗口管理器或桌面環(huán)境的啟動文件配置。 了解如何改變 $PATH變量很有用,它決定了shell尋找命令或程序的目錄路徑。若要執(zhí)行命令的目錄在$PATH中,用戶就不必輸入這個命令的完整路徑,能夠直
12、接執(zhí)行。第三方軟件一般沒有把可執(zhí)行文件放到標準目錄中,需要添加到$PATH中,才能保證程序的正常運行。 用戶如何處理一般的環(huán)境變量是有技巧的。所有環(huán)境變量名都大寫,用戶也可以自定義一些非大寫的變量,如$path、$pAtH,但shell 不知道這些變量。變量名有時以$開頭,有時不是。當(dāng)設(shè)置一個變量時,用戶直接用名稱而不需要加$,但要獲取變量的值就要在變量名前加$: $echo $PATH $/usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin 否則命令行$echo PATH的執(zhí)行結(jié)果就是:$PATH。,2020/9/26,11,處理$PATH變量時,用戶不能只
13、替換變量,而要將新字符串添加到原來的值中。用戶不能用PATH=/some/directory,這將刪除$PATH中的其它所有目錄。用戶在該終端運行程序時,必須給出完整路徑。所以只能添加: PATH=$PATH:/some/directory 當(dāng)用戶打開新終端運行echo $PATH時,返回的是舊$PATH值,看不到添加的新目錄。因為用戶定義的是局部環(huán)境變量。要定義全局變量,用戶需要將局部變量輸出(export),用export命令: export PATH=$PATH:/some/directory 現(xiàn)在打開新終端,輸入echo $PATH,將能看到新設(shè)置的$PATH。為了永久保存添加的路徑,
14、要將export行添加到用戶.bash_profile文件。 不要在.bashrc中設(shè)置PATH,以免PATH目錄意外增長。因為用戶每打開一個終端,目錄都會被添加,從而導(dǎo)致PATH變量目錄的多次復(fù)制。 (4)歷時記憶功能 bash命令的歷史功能是把以往輸入的命令記錄下來,方便日后查詢與再次使用。只要按向上鍵就能調(diào)出歷史命令。與SHIFT鍵連用,可遍歷該控制臺中的歷史輸出。歷史命令的編輯修改通過光標和Home、End等鍵完成。 用戶可以為環(huán)境變量HISTFILE賦新值改變存放歷史命令的文件,如: $ HISTFILE=/home/mengqc/.myhistory,2020/9/26,12,4.
15、3 shell基本命令,Linux中的shell命令很多,第三章已進行了解析,這里把與編程有關(guān)的命令羅列出來,便于讀者掌握。這些命令分為內(nèi)部命令和外部命令兩類。 4.3.1 內(nèi)部命令 shell內(nèi)部命令是shell本身具備的基本命令,執(zhí)行速度比外部命令快,存放在內(nèi)存中,在當(dāng)前shell中立即被執(zhí)行,不必創(chuàng)建新進程。編寫shell程序時盡量使用內(nèi)部命令,以提高程序的執(zhí)行效率。 不同shell的內(nèi)部命令大同小異,差別在于命令名或語法,用戶只要熟悉一種shell就可以了。表4.2以bash為例列出常用的內(nèi)部命令。,2020/9/26,13,2020/9/26,14,4.3.2 外部命令,shell除
16、去內(nèi)部命令以外的命令被稱為外部命令或程序。常用的有mv、ls、cp等。用戶在執(zhí)行外部命令時,shell首先查詢路徑找到該命令,然后生成子shell,由它解釋執(zhí)行這條命令。在命令執(zhí)行過程中,原shell(父shell)等待子shell的執(zhí)行而進入睡眠態(tài),一旦子shell執(zhí)行完畢,子shell將喚醒原shell,而子shell的生命周期到此結(jié)束。 4.3.3 命令分組 在shell中有兩種命令分組的方法:“( )”和“ ”。當(dāng)shell執(zhí)行()中的命令時將再創(chuàng)建一個新的子進程,然后這個子進程執(zhí)行圓括弧中的命令。當(dāng)用戶在執(zhí)行某個命令時,若不想讓命令運行對狀態(tài)集合的改變,影響后面語句的執(zhí)行時,就該把這
17、些命令放在括弧中,這樣就能保證所有的改變只對子進程產(chǎn)生影響,而父進程不受干擾。 用于將順序執(zhí)行的命令輸出結(jié)果用于另一個命令的輸入(管道方式)。當(dāng)用戶使用圓括弧和花括弧時,需要在其前面加上轉(zhuǎn)義符(、)以便shell知道他們不是用于命令執(zhí)行的終止之用。,2020/9/26,15,4.3.4 函數(shù),bash函數(shù)的實質(zhì)是命令集合或批處理文件。在shell中定義的函數(shù)都是由若干條shell命令組成的命令集合體,與shell程序形式相似,可看作一條復(fù)合命令。不同之處在于它是多進程。函數(shù)定義的基本格式為: function函數(shù)名( ) 若干命令行 其中關(guān)鍵字function可以缺省。調(diào)用函數(shù)的格式為: 函數(shù)
18、名 參數(shù)1 參數(shù)2 . shell函數(shù)可以完成一些例行工作,可以有自己的退出狀態(tài),所以函數(shù)可以作為if、while等控制結(jié)構(gòu)的條件。 在函數(shù)定義時一般不帶參數(shù),而在調(diào)用函數(shù)時帶參數(shù)運行,shell此時把參數(shù)分別賦予相應(yīng)的位置參數(shù)$1、$2、.及$*。 函數(shù)的規(guī)則是先定義后使用。調(diào)用函數(shù)時直接利用函數(shù)名,不帶圓括號,與一般命令同樣使用。shell腳本與函數(shù)間的參數(shù)傳遞可用位置參數(shù)和變量直接傳遞。變量值可以由shell腳本傳遞給被調(diào)用函數(shù),而函數(shù)中所用的位置參數(shù)$1、$2等對應(yīng)于函數(shù)調(diào)用語句中的實參,這與普通命令不同。,2020/9/26,16,【例】4.2,#func is a function
19、 name # it echos the values of variables and arguments func( ) echo Lets begin now. echo $a $b $c echo $1 $2 $3 echo The end. a= Working directory b=is c=pwd func Welcome You Byby echo Today is date shell中的函數(shù)把若干命令集合在一起,通過函數(shù)名調(diào)用。如果需要還可被多次調(diào)用。執(zhí)行函數(shù)并不創(chuàng)建新的進程,是通過shell進程執(zhí)行的。通常函數(shù)的最后一個命令執(zhí)行后就退出被調(diào)函數(shù)??梢杂胷eturn命令立
20、即退出函數(shù),其語法格式是: return n 其中的n值是退出函數(shù)時的退出值(退出狀態(tài)),即$?的值。當(dāng)n值缺省時,則退出值是最后一個命令執(zhí)行后的退回值。,2020/9/26,17,【例】4.3 定義4個函數(shù)并實現(xiàn)其功能,upper ( )函數(shù):將傳遞給它的文件中的字母轉(zhuǎn)換成大寫,并存放到同名的結(jié)尾為.out的文件中。 lower( ) 函數(shù):將傳遞給它的文件里的字母轉(zhuǎn)換成小寫,并存放到同名的結(jié)尾為.out的文件中。 print( ) 函數(shù):輸出傳遞給它的文件的內(nèi)容。 usage_error ()函數(shù):輸出程序的幫助信息。 程序的主模塊是case條件語句,根據(jù)命令行中第一個參數(shù)決定程序完成什么
21、功能,并調(diào)用相應(yīng)函數(shù)完成這個功能。,2020/9/26,18,4.3.5 shell的命令組合,Linux系統(tǒng)可以把系統(tǒng)命令、應(yīng)用程序和用戶程序有機地組合起來完成一系列任務(wù)。shell通過管道、輸入輸出重定向以及程序設(shè)計的方法來實現(xiàn)這一功能。通過這些方法,用戶可以靈活高效地使用shell控制linux系統(tǒng)的各種資源。 管道是把一個應(yīng)用程序的標準輸出與另外一個應(yīng)用程序的標準輸入相連接的有效工具。管道的基本格式為: 應(yīng)用程序管道操作符應(yīng)用程序 管道操作符是一個代表管道的專用字符“|”。管道線是由管道操作符分隔的幾個應(yīng)用程序組成的序列。管道線實現(xiàn)了創(chuàng)建管道文件并重定向輸入輸出的功能。管道重定向與I/
22、O重定向不同,前者直接把一個程序的輸出與另一個程序的輸入相連,不創(chuàng)建任何中間文件。Linux系統(tǒng)的一串管道線是一個命令表,送回的值是該命令表中最后一個管道線的出口狀態(tài)。 命令表中分隔命令的符號有“;”或換行符。否則,name的值就是該表達式的值。在第一種格式中,name值去掉的部分是與pattern匹配的最少的部分;而第二種格式中,name值去掉的部分是與pattern匹配的最多的部分。 表達式$name % pattern和$name % pattern,如果pattern與name值的末尾匹配,那么name的值中去掉匹配部分后的結(jié)果就是該表達式的值;否則,該表達式的值就是name的值。在第
23、一種格式中,去掉的部分是最少的匹配部分;而第二種格式中,去掉的部分是最多的匹配部分。 表達式$#和$#*的值分別是由$和$*返回的參數(shù)的個數(shù)。 表達式$#namei的值是數(shù)組name第i個元素值的長度。 表達式$#name*和$#name的值都是數(shù)組name的元素個數(shù)。,2020/9/26,32,4.4.5 鍵盤輸入變量,利用read命令可從鍵盤讀數(shù)據(jù)賦給指定變量。read命令的一般格式是: read 變量1 變量2 。例如: read a b c 輸入數(shù)據(jù)時,數(shù)據(jù)間以空格或制表符分隔。如果變量個數(shù)與給定數(shù)據(jù)個數(shù)相同,則依次對應(yīng)賦值;如果變量個數(shù)少于數(shù)據(jù)個數(shù),則從左至右對應(yīng)賦值,但最后一個變量
24、被賦予剩余的所有數(shù)據(jù);如果變量個數(shù)多于給定數(shù)據(jù)個數(shù),則依次對應(yīng)賦值,而沒有數(shù)據(jù)與之對應(yīng)的變量取空串。,2020/9/26,33,4.4.6 位置變量,在執(zhí)行l(wèi)inux命令或shell腳本時可以用實參替代位置變量,它們的名稱很特別,分別是0、1、29。因為它們與命令行上具體位置的實參相對應(yīng):命令名(文件名)對應(yīng)位置變量0,第一個實參對應(yīng)位置變量1,第二個實參對應(yīng)位置變量2如果位置變量是由兩個或更多個數(shù)字構(gòu)成,必須把它們用一對花括號括起來,如10、11。命令行實參與腳本中位置變量的對應(yīng)關(guān)系如下: comm c1 c2 c3 c4 c10 c11 $0 $1 $2 $3 $4 $10 $11 【例】
25、4.7 $ set pwd;ls;date $ echo $1 $2 $3 $9 $10 $11 /home/mengqc bash_1 ex1 12 3 21:52:32 在cygwin中的應(yīng)用情況見圖4.1所示。,2020/9/26,34,如果在腳本中使用的位置參數(shù)不超過9個,那么只用$1$9即可。但是,實際給定的命令行參數(shù)有可能超過9個,此時就要用shift命令移動位置參數(shù)。每執(zhí)行一次shift命令,就把命令行上的實參向左移一位,即相當(dāng)于位置參數(shù)向右移動一個位置,如表4.3所示。 表4.3 位置變量的shift對應(yīng)關(guān)系 命令行Ex7ABCDEF原位置參數(shù)$0$1$2$3$4$5$6新位置
26、參數(shù)$0$1$2$3$4$5表4.3列出了實參與位置參數(shù)的對應(yīng)關(guān)系??梢钥闯?,shift命令執(zhí)行后新$1的值是原$2的值,新$2的值是原$3的值,依此類推。shift命令不能將$0移走,所以經(jīng)shift右移后, $0的值不會變化,見圖4.2所示。,2020/9/26,35,4.4.7 預(yù)定義特殊變量,shell中預(yù)定義的特殊含義的shell變量值只能由shell根據(jù)實際情況賦值,不能通過用戶重新設(shè)置。下面給出這些特殊變量的表示形式及意義。 $# 命令行上實際參數(shù)的個數(shù),不包含shell文件名。 $?上一條命令執(zhí)行后的返回值(也稱為“退出碼”),是一個十進制數(shù)。多數(shù)shell命令執(zhí)行成功時,返回
27、值為0;執(zhí)行失敗則返回非0值。 圖4.2 shift右移位置參數(shù)的變化情況 $ 當(dāng)前進程的進程號。 $!上一個后臺命令對應(yīng)的進程號,是由15位數(shù)字構(gòu)成的數(shù)字串。 $- 由當(dāng)前shell設(shè)置的執(zhí)行標志名組成的字符串。例如: set -xv 這個命令行給shell設(shè)置了標志-x和-v(用于跟蹤輸出)。 $*表示命令行中實際給出的所有實參字符串,不限于9個實參。 $ 它與$*基本功能相同,但“$”與“$*”不同。 $ 0 :保存程序名。,2020/9/26,36,4.4.8 環(huán)境變量與置換變量,PWD是指用戶當(dāng)前目錄的全名 PPID是指父進程ID $是指當(dāng)前進程ID UID是指當(dāng)前用戶的User I
28、D PATH是指查找命令的目錄列表。 PATH變量含帶冒號符的字符串。 USER是指用戶賬號MAIL是指系統(tǒng)信箱的路徑。 TERM是指終端類型。 LOGNAME是用戶登錄名 SECONDS是指當(dāng)前運行的bash進程的運行時間(以秒為單位) HOME是指用戶home目錄的路徑名,是cd命令的默認參數(shù) COLUMNS是指定義了命令編輯模式下可使用命令行的長度 EDITOR是指默認的行編輯器 IFS是定義SHELL使用的分隔符 TMOUT SHELL指自動退出時間(秒),設(shè)為0禁止SHELL自動退出 PS1是指主命令提示符 PS2指二級命令提示符,要求輸入數(shù)據(jù)時用 PS3是select的命令提示符P
29、S4是指調(diào)試命令提示符 LD_LIBRARY_PATH是指尋找?guī)斓穆窂?,以冒號分隔?參數(shù)置換變量的一般形式是:變量2=$ 變量1 op 字符串 其中op表示操作符,它可以是下列四個操作符之一“:-”、“:=” 、“: +” 和“: ?”。變量2的值取決于變量1(參數(shù))是否為空串、用什么操作符及字符串的取值。在操作符的前后不要留空格。,2020/9/26,37,4.4.9 算術(shù)運算,bash中的整數(shù)算術(shù)運算命令是let,其語法格式為:let arg 其中arg是單獨的算術(shù)表達式,使用的是C語言中表達式的語法、優(yōu)先級和結(jié)合性。除+、-和逗號(,)之外,所有整型運算符都能支持。提供方冪運算符“*”
30、。命名的參數(shù)可以在算術(shù)表達式中直接利用名稱訪問,前面不帶“$”符號。當(dāng)訪問命名參數(shù)時,就作為算術(shù)表達式計算它的值。算術(shù)表達式按長整數(shù)進行求值,不檢查溢出。但用0作除數(shù)就會產(chǎn)生錯誤。 let 命令的替代表示形式是: (算術(shù)表達式) 例如,let j=i*6+2等價于(j=i*6+2)。 如果表達式的值是非0,那么返回狀態(tài)值0;否則返回狀態(tài)值1。當(dāng)表達式中有shell的特殊字符時,必須用雙引號將其括起來。【例】如,let val=a|b。如果不括起來,shell會把命令行l(wèi)et val=a|b中的“|”看成管道符,將其左右兩邊看成不同的命令,因而無法正確計算表達式的值。,2020/9/26,38,
31、4.5 shell程序流程,shell具有一般高級程序設(shè)計語言所具有的控制結(jié)構(gòu)等復(fù)雜功能,如if語句、 case語句、循環(huán)結(jié)構(gòu)和函數(shù)等。 4.5.1 測試語句test 條件測試有三種常用形式:一是test命令,二是一對方括號,這兩種形式是完全等價的。三是兩對方括號,即 條件表達式 。test命令可以和多種系統(tǒng)運算符一起使用,這些運算符可以分為四類:文件屬性及權(quán)限測試運算符、字符串測試運算符、數(shù)值測試運算符和邏輯運算符。與傳統(tǒng)語言不同,shell用于指定條件值的不是布爾表達式而是命令和字符串。,2020/9/26,39,test測試命令用法,Test命令用于檢查某個條件是否成立,它可以進行數(shù)值、
32、字符和文件三個方面的測試,其測試符和相應(yīng)的功能分別如表4.4所示。 test可以對字符串、整數(shù)和文件進行條件測試。 Linux還提供了與(“!”)、或(“-o”)、非(“a”)三個邏輯操作符用于將測試條件連接起來,其優(yōu)先級為:“!”最高,“-a”次之,“-o”最低。 test命令的格式為: test expression或者 expression 其中的expression是被測試的條件。若test expression或者 expression 的結(jié)果為真,則返回0,否則非0。注意expression和 之間必須有空格。,2020/9/26,40,字符串比較,字符串比較可以測試字符串長度是否
33、為0以及兩個字符串是否相等。下面用例子來說明對字符串進行測試的方法。 【例】4.8 判斷兩個字符串是否相同。 $ test long = long;echo $? 0 $ test long = short ;echo $? 1 值得注意的是在“=”號兩邊一定要有空格,否則就會產(chǎn)生賦值歧義。 使用test測試字符串時要注意的問題:向test傳遞的各自變量間必須有空白符,如果“=”與任一自變量之間沒有空白字符就會產(chǎn)生錯誤。在用變量值替換的自變量上,必須用雙引號括起來,以保證test在變量的值為空時也能接收到該自變量,這是一種良好的shell程序設(shè)計風(fēng)格。,2020/9/26,41,數(shù)字比較,te
34、st 命令可以用來比較整數(shù)?;菊Z法是: test int1 op int2或者 int1 op int 2 其中int1 和int2 可以是任何正整數(shù)或負整數(shù)。 【例】4.9 $ x1=”005” $ x2=”10” $ test “$x1” = 5 $ echo $? 1 【例】4.10 把005 ,5當(dāng)作字符串來看待。當(dāng)使用整數(shù)比較操作符時,把005,5當(dāng)作整數(shù)來看待,整數(shù)的005和5是相等的。,2020/9/26,42,文件測試,文件測試表達式測試一個文件是否滿足特殊條件,其通用語法是: test option name或者 option name 其中name 是文件的名字或目錄的名
35、字,option和測試的結(jié)果如下所示: 【例】4.11 檢查指定的name是否為目錄 $ test d /home $ echo $? 0 當(dāng)一個shell命令或程序執(zhí)行成功時,返回0;如果執(zhí)行失敗,則返回非0。除了一般命令的出口狀態(tài)外,Linux系統(tǒng)還提供了true和false兩個命令。true的返回值為0,而false的返回值為非0。shell可使用true和false作為恒真和恒假條件使用,用命令可以查看這兩個命令的返回值。 如果命令行是由幾個應(yīng)用程序和管道操作符組成的命令表,則整個命令行的返回值是該命令表中的最后一個應(yīng)用程序的返回值。,命令行的屬性值,2020/9/26,43,4.5.
36、2 條件語句if,條件語句是最簡單最基本的控制結(jié)構(gòu)。根據(jù)對條件的判斷來決定執(zhí)行哪一組命令。這種語句的語法格式為: if 表達式 then 命令表 fi 該語句先執(zhí)行表達式,如果表達式為真,則執(zhí)行命令表,否則退出if語句。如果用戶希望在表達式返回的值為假時,不退出if而轉(zhuǎn)去執(zhí)行其他命令表,可以使用if語句的完整結(jié)構(gòu),如下所示: if 表達式 then 命令表1 else 命令表2 fi 該語句先執(zhí)行表達式,若表達式值為真則執(zhí)行命令表1,否則執(zhí)行命令表2。 為了滿足用戶更多要求和便于編程,shell還提供if語句的嵌套結(jié)構(gòu),把多個if語句連用,完成用戶更復(fù)雜的要求和判斷。連用結(jié)構(gòu)如下: if 表達
37、式1;then 命令表1 else if 表達式2; then 命令表2 else if 表達式3; then 命令表3 else 命令表4 fi fi fi 這是一個if語句的三重結(jié)構(gòu),還可以有更多重的復(fù)雜結(jié)構(gòu)。這種結(jié)構(gòu)采用簡潔方式,把if和then放在一行,但在then之前要加“;”號。,2020/9/26,44,【例】4.12 當(dāng)用戶將某文件作為設(shè)定文件時,先檢查是否存在,然后將該文件的設(shè)定值載入。 #Filename : /etc/ppp/settings PHONE=1-800-COLLECT #!/bin/sh #Filename : phonebill if -f /etc/pp
38、p/settings ; then source /etc/ppp/settings echo $PHONE fi 執(zhí)行結(jié)果情況: foxmanfoxman ppp# ./phonebill 1-800-COLLECT,2020/9/26,45,【例】4.13 如果某個設(shè)定文件允許有好幾個位置的話,例如crontab,可利用if then elif fi來找尋。 #!/bin/sh if -f /etc/crontab ; then CRONTAB=/etc/crontab elif -f /var/spool/cron/crontabs/root ; then CRONTAB=/var/sp
39、ool/cron/crontabs/root elif -f /var/cron/tabs/root ; then CRONTAB=/var/cron/tabs/root fi export CRONTAB,2020/9/26,46,4.5.3 開關(guān)語句case,Bash中的case結(jié)構(gòu)與C語言中switch功能相似,用于多分支控制。 【例】4.14運用 case 結(jié)構(gòu)進行分支選擇。 #!/bin/bash echo Hit a key, then hit return. read Keypress case $Keypress in a-z ) echo Lowercase letter;
40、A-Z ) echo Uppercase letter; 0-9 ) echo Digit; * ) echo Punctuation, whitespace, or other; esac exit 0 其中第四行的read Keypress的read語句是從鍵盤讀輸入。,2020/9/26,47,開關(guān)語句case允許把一個和多個選項值進行比較。結(jié)果匹配就轉(zhuǎn)到相應(yīng)的命令表,直至遇到兩個分號為止。如果沒有匹配值,則執(zhí)行默認命令。此語句的基本形式結(jié)構(gòu)為: case 變量 in 選項1) 命令表1; 選項n) 命令表n; esac 在case語句中,每個選擇中的命令表都以“;”結(jié)束,表示跳出開關(guān)語
41、句,最后一個“;”可省略。,2020/9/26,48,2020/9/26,49,2020/9/26,50,4.5.4 循環(huán)語句for,shell中有for、while和until三種循環(huán)語句。for結(jié)構(gòu)與C語言中有所不同,針對的是一組命令進行多次執(zhí)行的循環(huán)體?;菊Z法結(jié)構(gòu)為: for 變量名 in 變量表 do 命令表 done 變量名是用戶所使用的循環(huán)變量的名字。變量表中是取值范圍和循環(huán)執(zhí)行次數(shù)。do和done中間的命令表稱為循環(huán)體。當(dāng)執(zhí)行循環(huán)時,系統(tǒng)依次把變量表中的變量賦給變量,然后執(zhí)行命令表,直到變量表中的所有變量都執(zhí)行一遍為止。 變量名可以是用戶選擇的任何字符串,如果變量名是var,則
42、在in之后給出的數(shù)值將順序替換循環(huán)命令列表中的$var。如果省略了in,則變量var取值是位置變量。對變量的每一個可能賦值都將執(zhí)行do和done之間的命令列表。 【例】4.17 在屏幕上打出17這七個數(shù)字。 $ cat showprog for i in 1 2 3 4 5 6 7 do echo $i done,2020/9/26,51,2020/9/26,52,【例】4. 18 運用for語句來實現(xiàn)循環(huán)。 #!/bin/bash for day in Sun Mon Tue Wed Thu Fri Sat do echo $day done 【例】4.19 分析下面的這個程序。 #!/bi
43、n/bash for param do echo $param done exit 0 上面這個程序?qū)⒘谐鏊忻钚兄薪o出的參數(shù)。,2020/9/26,53,【例】4.20 修改文件類型名。 把*.txt文件一次性改名成*.doc文件。 #!/bin/sh FILES=ls /txt/*.txt for txt in $FILES ; do doc=echo $txt | sed s/.txt/.doc/ mv $txt $doc done 這樣可以將*.txt文件修改成*.doc文件。 【例】4.21編寫程序catmore實現(xiàn)多文件內(nèi)容顯示。 #!/bin/sh # Filename : c
44、atmore for i ; do cat $i done 當(dāng)用戶輸入catmore file1 file2 .時,其作用就跟cat file1 file2 .一樣。,2020/9/26,54,【例】4.22 編寫程序文件listbin實現(xiàn)ls /bin/*的功能。 #!/bin/sh # Filename : listbin for i in /bin/* ; do echo $i done 【例】4.23 改寫Red Hat的啟動文件/etc/rc.d/rc,在其中加上命令找出/etc/rc.d/rcX.d/S*所有文件,檢查存在與否并一一執(zhí)行。 for i in /etc/rc.d/rc
45、$runlevel.d/S*; do # Check if the script is there. ! -f $i 接收用戶的輸入,并且將輸入的值存放在特定變量里. if $res= y -o $res= Y then break ;用于退出while,for,select等循環(huán)語句 fi done select name in word; do list ; done select顧名思義就是在word中選擇一項。與for相同,如果in word;省略,將會使用Script后面所加的參數(shù)。,2020/9/26,61,4.5.9 shift語句和repeat語句,bash和tcsh都支持sh
46、ift命令。shift將存放在位置變量中的命令行參數(shù),依次向左傳遞。例如位置變量當(dāng)前值為: $1=file1 $2=file2 $3=file3 執(zhí)行一次shift命令后,位置變量的值為: $1=file2 $2=file3 還可以在shift命令中指定位置變量轉(zhuǎn)移的次數(shù), 如: #shift n。 。使用repeat要求shell對一個命令執(zhí)行一定的次數(shù)。 語法格式: #repeat count command 【例】4.28 repeat的使用。 foreach num ( $ *) repeat $num echo -n * echo end 本程序的運行結(jié)果見圖4.5所示。,2020/
47、9/26,62,4.6 程序調(diào)試,當(dāng)shell程序較長較復(fù)雜或用于修改系統(tǒng)配置時就需要調(diào)試命令。shell提供了幾種對程序調(diào)試的命令,可以觀察程序的執(zhí)行,或程序在不做任何實際處理情況下是如何被“執(zhí)行”的。 語法檢查 shell的語法檢查允許用戶在執(zhí)行shell程序前先檢查shell程序的語法,但不執(zhí)行命令行。語法檢查命令的基本格式為: sh n 文件名 或 set n,2020/9/26,63,【例】4.29 對下面的文件名為t2的shell腳本進行語法檢查。 a=1 if a = 1 echo $a fi 用語法檢查命令檢查該程序: $ sh -n t2 則屏幕上顯示: t2: line 4
48、 :syntax error near unexpected token fi t2 :line 4 :fi 檢查命令在試圖讀第4行時,發(fā)現(xiàn)if語句沒有正確結(jié)束。因為第2行的if語句沒有用then語句正確結(jié)束。把if a = 1 這一行改為: if a = 1 ;then 再用語法檢查命令檢查該程序,就沒有語法錯誤了。,2020/9/26,64,shell程序的詳細跟蹤 shell詳細跟蹤特性允許用戶觀察shell程序的讀入和執(zhí)行。命令行被讀入后,shell按讀入時的形式在標準輸出中顯示該命令行,然后執(zhí)行命令行。詳細跟蹤有兩種方式: (1)整個程序的跟蹤執(zhí)行:sh -v 文件名。 (2)局部跟
49、蹤執(zhí)行:set v用于設(shè)置跟蹤標志;set +v用于關(guān)閉跟蹤標志。 shell程序的跟蹤執(zhí)行 shell允許用戶觀察shell程序的執(zhí)行。它使命令行在執(zhí)行前完成所有替換,在標準輸出中顯示每一個被替換后的命令行,并且在行前加前綴符號“”,然后執(zhí)行該命令。跟蹤執(zhí)行也有兩種方式: (1)整個程序的跟蹤執(zhí)行:sh -x 文件名。 (2)局部跟蹤執(zhí)行:set x用于設(shè)置跟蹤標志;set +x用于關(guān)閉跟蹤標志。,2020/9/26,65,詳細跟蹤與跟蹤執(zhí)行的組合 基本格式為: (1)整個程序的跟蹤執(zhí)行:sh vx 文件名。 (2)局部跟蹤執(zhí)行:set vx設(shè)置跟蹤標志;set +vx關(guān)閉跟蹤標志。 詳細跟
50、蹤和跟蹤執(zhí)行的區(qū)別在于:在執(zhí)行命令前,詳細跟蹤顯示命令行的原始內(nèi)容,而跟蹤執(zhí)行則顯示經(jīng)過替換后的命令行的內(nèi)容。,2020/9/26,66,【例】4.30 分析對于下面的程序t4的詳細跟蹤與跟蹤執(zhí)行的情況,b=“005” test “$b” eq 5 echo $? 詳細跟蹤命令: $sh v t4 跟蹤執(zhí)行命令: $sh x t4 詳細跟蹤與跟蹤執(zhí)行的組合情況: $sh vx t4 b=“005” +b=005 test “$b” eq 5 +test 005 eq 5 echo $? +echo 0 0 所有這些選項也可以在一個shell程序內(nèi)部用“set -選項”的形式引用,而“set 選
51、項”將禁止該選項起作用。,2020/9/26,67,5. 腳本調(diào)試,基本格式:#sh nvx 其中-n 檢查語法錯誤,不執(zhí)行;-v 執(zhí)行前先顯示代碼;-x 執(zhí)行后顯示用到的代碼。調(diào)用shell 的形式是: sh -選項 程序名 其中選項是:-n讀入命令但不執(zhí)行。-v讀入shell輸入行時把它們顯示出來。-x執(zhí)行命令時把命令和它們的參數(shù)顯示出來。所有這些選項也可以在一個shell程序內(nèi)部用“set -選項”的形式引用,而“set 選項”將禁止該選項起作用。,2020/9/26,68,6. 信號與trap,當(dāng)?shù)玫叫盘柕臅r候怎么辦,具體的信號可以用trap -l來看。使用方法: trap comma
52、nd signal_name 常用的有:HUB掛起,如斷線;INT中斷,如Ctrl+C;QUIT退出,如Ctrl+;ABRT終止,執(zhí)行錯誤等;ALRM超時報警;TERM系統(tǒng)終止,如root關(guān)機。 trap命令用于在shell程序中捕捉到信號,然后采取三種不同的反應(yīng): (1)執(zhí)行一段程序來處理這一信號。trap命令在shell接受到signal list清單中數(shù)值相同的信號時,將執(zhí)行雙引號中的命令串。 trap commands signal-list trap “commands”signal-list (2)接受信號的默認操作。 trap signal-list,2020/9/26,69,(
53、3)忽略這一信號。trap Signal-list 但trap對信號11(段違例)不能捕捉,因為shell需要捕捉該信號進行內(nèi)存轉(zhuǎn)儲。在trap中可以定義對信號0的處理(實際上無此信號),shell程序在其終止(如執(zhí)行exit)時發(fā)該信號。在捕捉到signal -list中指定的信號并執(zhí)行完相應(yīng)的命令后,如果這些命令沒有將shell程序終止,shell將繼續(xù)執(zhí)行受到信號時執(zhí)行命令后面的命令,但容易導(dǎo)致shell程序無法終止。 在trap語句中,單引號和雙引號不同,當(dāng)shell第一次碰到trap語句時將把commands中命令掃描一遍。若commands在單引號里,shell不會對command
54、s中的變量和命令替換,否則commands中的變量和命令將用當(dāng)時具體值替換。,2020/9/26,70,4.7 shell編程綜合范例,4.7.1系統(tǒng)自動備份程序設(shè)計 利用shell Script搭配crond可以完成定期的工作。如對系統(tǒng)的備份問題,可以用一些壓縮工具。tar及gzip是最基本的。用戶會看見大量的tar.gz或tgz文件,被稱為tarball。用戶也可以用bzip2、zip等壓縮工具來進行壓縮,但tar配合gzip是最普遍最方便的組合方式。最常用的指令是: tar -c file/dir . | gzip -9 xxxx.tar.gz。 也可以分兩步完成:tar -r file
55、/dir . -f xxx.tar和gzip -9 xxxx.tar或 tar -r file/dir . -f xxxx.tar 和gzip -9 xxxx.tar.gz。,2020/9/26,71,完成文件備份任務(wù)的backup程序,#!/bin/sh # Filename : backup DIRS=/etc /var /your_directories_or_files BACKUP=/tmp/backup.tgz tar -c $DIRS | gzip -9 $BACKUP 其中DIRS是備份目標,BACKUP是備份文件名稱和存放位置。不要將/tmp放進DIRS中,這樣會自身重復(fù)備份
56、,導(dǎo)致硬盤空間溢出錯誤。 下面進行腳本測試: # chmod 755 backup # ./backup 執(zhí)行完成后在/tmp中會生成一個名為backup.tgz的備份文件。 解壓時,請用gzip -dc /tmp/backup.tgz | tar -xv指令完成,或 tar xvfz /tmp/backup.tgz。 備份對象一般是系統(tǒng)中最重要的,如/etc中的文件,更重要的是用戶資料。對于/bin、/sbin、/usr/bin、/usr/sbin、/usr/X11R6/bin等系統(tǒng)文件目錄可不備份。 通過簡單的shell腳本程序配合cron定時工具,就把原本耗費多時的人工備份工作,簡化到幾
57、分鐘的自動工作,提高了效率和可靠性。,2020/9/26,72,4.7.2 終端顏色搭配的color腳本,#!/bin/bash #filename:bashcolor # This file echoes a bunch of color codes to the terminal to demonstrate whats available. Each line # is the color code of one forground color # out of 17 (default + 16 escapes), followed by a test use # of that col
58、or on all nine background colors (default + 8 escapes). T=gYw # The test text echo -e n 40m 41m 42m 43m 44m 45m 46m 47m; for FGs in m 1m 30m 1;30m 31m 1;31m 32m 1;32m 33m 1;33m 34m 1;34m 35m 1;35m 36m 1;36m 37m 1;37m; do FG=$FGs/ / echo -en $FGs 033$FG $T for BG in 40m 41m 42m 43m 44m 45m 46m 47m; d
59、o echo -en $EINS 033$FG033$BG $T 0330m; done echo; done echo 還有一種更適當(dāng)?shù)脑O(shè)定是:PS1=u: w$ ;這時的提示符會變成:user_name: /usr/bin$ 可通過命令export測試不同的設(shè)置(比如,export PS1=u: w$ )。,2020/9/26,73,4.7.3目錄菜單編制程序,2020/9/26,74,4.7.4 問題交互圖形化設(shè)計例程,圖形化問題交互直觀友好,在此程序中可以進行交互式問答。通過選擇不同的選項得到不同的結(jié)果,采用幾個圖形函數(shù)實現(xiàn)了交互功能。 #!/bin/sh # Ask some questions and collect the answer #filename:quesinter.sh dialog -title 1:Questionnaire -msgbox Welcome to my simple survey 9 18 dialog -title :Confirm -yesno Are you willing to take part? 9
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 肝與腎中醫(yī)課件
- 肛腸健康講座課件
- 關(guān)于對稱的數(shù)學(xué)試卷
- 福建省教招小學(xué)數(shù)學(xué)試卷
- 肌內(nèi)效貼布技術(shù)課件
- 2025年05月浙江麗水市縉云縣衛(wèi)生健康系統(tǒng)招聘工作人員自愿放棄復(fù)審人員及人員筆試歷年專業(yè)考點(難、易錯點)附帶答案詳解
- 2025至2030船舶卸貨系統(tǒng)行業(yè)市場深度研究與戰(zhàn)略咨詢分析報告
- 2025至2030寵物衣服行業(yè)市場深度研究與戰(zhàn)略咨詢分析報告
- 廈門市政投資有限公司招聘考試真題2024
- 2024年商洛山陽縣信毅學(xué)校招聘筆試真題
- 科技公司信息安全二級等保建設(shè)方案
- 聯(lián)合體內(nèi)部合作協(xié)議書
- 語文學(xué)科核心素養(yǎng)
- TYCST 004-2024 透水水泥穩(wěn)定碎石基層 透水系數(shù)的測定
- 部門級安全培訓(xùn)試題加解析答案可打印
- 廣西版五年級下冊美術(shù)全冊教案【完整版】
- 2024年清理道路塌方協(xié)議書模板
- 車間6S可視化管理之定置劃線標準解讀
- GB/T 24067-2024溫室氣體產(chǎn)品碳足跡量化要求和指南
- GB 44495-2024汽車整車信息安全技術(shù)要求
- Odoo:Odoo集成與第三方應(yīng)用技術(shù)教程.Tex.header
評論
0/150
提交評論