華東理工大學(xué)Linux系統(tǒng)linux04_第1頁
華東理工大學(xué)Linux系統(tǒng)linux04_第2頁
華東理工大學(xué)Linux系統(tǒng)linux04_第3頁
華東理工大學(xué)Linux系統(tǒng)linux04_第4頁
華東理工大學(xué)Linux系統(tǒng)linux04_第5頁
已閱讀5頁,還剩111頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

Linux系統(tǒng)與編程第4章Linux下的shell編程EcustChinaUniversityofScienceandTechnology本章內(nèi)容

第1節(jié)shell概述

第2節(jié)shell的基本功能

第3節(jié)shell的啟動及其命令

第4節(jié)shell命令的集成

第5節(jié)shell變量

第6節(jié)shell的控制結(jié)構(gòu)

第7節(jié)shell的運(yùn)行環(huán)境

第8節(jié)shell應(yīng)用實(shí)例2第1節(jié)shell概述

什么是shell

shell程序語言的特點(diǎn)

shell的版本3什么是shell

Shell是一種命令解釋程序(命令解釋器),shell解釋用戶輸入的命令行,提交系統(tǒng)內(nèi)核處理,并將結(jié)果返回給用戶。與Linux命令一樣都是實(shí)用程序,但兩者又有區(qū)別。一旦用戶注冊到系統(tǒng)后,shell就被系統(tǒng)裝入內(nèi)存,并一直運(yùn)行到用戶退出系統(tǒng)為止,而一般命令僅當(dāng)被調(diào)用時才由系統(tǒng)裝入內(nèi)存運(yùn)行。

Shell本身也是一種可編程的設(shè)計(jì)語言。用shell寫的程序(shell腳本)相當(dāng)于dos/windows下的批處理文件,它可以簡單到只有一條命令,也可以復(fù)雜到包括大量循環(huán)、條件語句、數(shù)學(xué)運(yùn)算、控制結(jié)構(gòu),也可以是介于兩者之間的程序。4Shell程序語言的特點(diǎn)Shell允許通過編程來完成復(fù)雜的功能處理,但其作為語言與高級語言相比較具有不同的特點(diǎn)(1)shell是解釋性的,多數(shù)高級語言是編譯性的(2)shell語言與高級語言處理的對象不同(3)shell與系統(tǒng)有密切的關(guān)系(4)shell易編寫、調(diào)試、靈活性強(qiáng),但速度低(5)shell作為命令級語言,命令組合功能很強(qiáng)5Shell的版本Shell有兩種主要語法類型:Bourneshell和Cshell,彼此不兼容。Bourneshell家族:shkshbashpshzsh;Cshell家族:cshtcshbash的特點(diǎn):(1)自動補(bǔ)全(2)命令行編輯程序(3)命令歷史6第2節(jié)shell的基本功能

程序的運(yùn)行

使用保留字和元字符

變量、文件名的替換

輸入輸出重定向

運(yùn)行環(huán)境的控制

支持shell的編程7程序的運(yùn)行

當(dāng)用戶輸入一行命令后,shell負(fù)責(zé)解釋、分析輸入的內(nèi)容,并且決定做什么,同時替系統(tǒng)內(nèi)核刪除命令行中不必要的信息。命令是一個可執(zhí)行的Linux命令、程序、工具或shell腳本。例1:$ls–lfile1file2例2:$echo‘welcome’例3:$echowelcome注意:例2和例3的結(jié)果是完全一樣的。8使用保留字和元字符

Shell有一些具有特殊意義的字(保留字),如在shell腳本中,像do、done、for等保留字控制循環(huán)操作,if、then等保留字進(jìn)行條件控制。保留字隨shell的不同而不同。

在Linux系統(tǒng)里,有一組特殊意義字符,這就是所謂的元字符(通配符)。比如:..上一層目錄字符.當(dāng)前工作目錄*任意長度的例:ls–xt*顯示當(dāng)前目錄下以t打頭的所有文件9變量、文件名的替換

Shell允許對變量賦值。Shell一旦在命令行中發(fā)現(xiàn)$變量名時,將在$變量名的位置上用以前賦給該變量的值替代$變量名

例:$myhome=/usr/app$echo$myhome/usr/app$ls–x$myhomefile1file2file310變量、文件名的替換

Shell在命令行中將文件名進(jìn)行替換。事實(shí)上,shell在確定要執(zhí)行的程序名和它的自變量之前,要對命令行掃描,找出元字符進(jìn)行相應(yīng)的文件名的替換。

例:$ls-xfile1file2file3$echo*file1file2file311輸入輸出重定向

Shell處理命令行的輸入輸出重定向,它掃描命令行中特殊改向字符“>”、“<”,將輸入或輸出改向到指定的文件中。

例:$echo“pleasecallme”>msg$catmsgpleasecallme12運(yùn)行環(huán)境的控制

當(dāng)用戶登錄到Linux系統(tǒng)中,系統(tǒng)啟動一個交互式的shell沒弄過了解釋器(稱為注冊shell)。該shell為此用戶創(chuàng)建工作環(huán)境。Shell提供了一定的命令,允許用戶對自己運(yùn)行的環(huán)境進(jìn)行控制,即對運(yùn)行環(huán)境實(shí)現(xiàn)客戶化。用戶的運(yùn)行環(huán)境包括:主目錄、終端類型、輸入命令提示符等。

例如:Bourneagainshell、Bourneshell、Kornshell和Cshell的環(huán)境文件分別為.bash-profile、.profile、.kshrc和.cshrc13支持shell的編程

Shell除了具有命令解釋器的功能外,它本身就是一種程序設(shè)計(jì)語言,這種語言也由shell解釋執(zhí)行的。用戶可以在文件中編寫一組shell命令,該文件稱為shell腳本或shell程序。通過把命令、變量賦值及條件控制語句結(jié)合起來,用戶就獲得了一個強(qiáng)大的編程工具。需要說明的是,在Linux系統(tǒng)本身就存在大量的shell程序,用于各種管理和應(yīng)用。14第3節(jié)shell啟動和命令

Shell的啟動

命令的查詢

Shell常用的命令

Shell的內(nèi)部命令15Shell的啟動一:系統(tǒng)在用戶登錄時啟動shell

在Linux系統(tǒng)引導(dǎo)過程中,首先啟動init進(jìn)程以查詢終端的各個端口及其特性,當(dāng)發(fā)現(xiàn)活動的終端時,調(diào)用getty進(jìn)程。接著getty進(jìn)程在接受用戶名和口令后,調(diào)用login進(jìn)程。Login進(jìn)程負(fù)責(zé)驗(yàn)證用戶身份,驗(yàn)證后把控制權(quán)交給shell程序。Shell根據(jù)環(huán)境文件建立系統(tǒng)范圍內(nèi)的工作環(huán)境和該用戶自己的工作環(huán)境,最后顯示命令提示符(#、$、%)16Shell的啟動二:命令行狀態(tài)下的交互shell啟動

在系統(tǒng)中可能有多種版本的shell存在,可通過相應(yīng)的命令來啟動,如:$bsh$ksh$sh17Shell的啟動二:執(zhí)行用戶命令時啟動shell

由系統(tǒng)生成新的子shell來執(zhí)行該命令18命令的查詢

環(huán)境變量PATH的構(gòu)成決定了尋找shell命令和其它程序的途徑,是影響shell程序效率的主要因素之一。PATH變量設(shè)置要考慮一下幾點(diǎn):在PATH變量中,命令使用得多的程序目錄應(yīng)該放在前面,極少用目錄不設(shè)在PATH變量中。在shell程序內(nèi)用的較多的程序目錄應(yīng)加在PATH中。并且PATH應(yīng)盡可能地短,不要出現(xiàn)重復(fù)的目錄。還要盡量避免查詢大目錄,如需設(shè)置,將其路徑放在PATH路徑的最后位置

例:PATH=/bin:/usr/bin:/etc:19Shell常用的命令Linux系統(tǒng)通常提供了許多命令以方便用戶與系統(tǒng)的交互對話。這些命令的選項(xiàng)較多,并且可利用命令的集成(如輸入輸出改道、管道機(jī)制)及程序設(shè)計(jì)功能組合成許多命令。Linux有豐富的shell命令,大致劃分為以下幾類:目錄操作與管理、文件操作與管理命令、系統(tǒng)管理與維護(hù)、用戶管理與維護(hù)、系統(tǒng)狀態(tài)、進(jìn)程管理、通訊命令、其他命令。例如,awkcatchmodchowncpcrondatedfdiffduechoexprfilefindgrepinitkilllnloginlsmailmakemanmkdirmvnohuppgpspwdreadrmwc20Shell常用的命令通常情況下,在用戶輸入一個命令(非內(nèi)部命令)時,注冊shell首先通過查詢路徑查找該命令,然后生成出一個副本(稱為該shell的子shell),由子shell來負(fù)責(zé)解釋執(zhí)行這個命令。在命令執(zhí)行過程中,注冊shell(父shell)等待子shell的執(zhí)行而進(jìn)入睡眠態(tài),一旦子shell執(zhí)行完畢,子shell將喚醒注冊shell(父shell),而自己的生命周期到此結(jié)束。21Shell的內(nèi)部命令內(nèi)部命令構(gòu)造在shell的內(nèi)部。內(nèi)部命令比非內(nèi)部命令的執(zhí)行速度要快。因此,編寫shell程序時應(yīng)盡量地使用shell的內(nèi)部命令。shell常用的內(nèi)部命令有:#注釋命令,#后面的內(nèi)容作為注釋信息。:空命令,通常放在一行的最左邊,實(shí)際不做任何命令,只返回出口代碼0。其他命令有:cd,eval,set,unset,exec,exit,if,else,for,case,while,until,continue,break等。22第4節(jié)shell命令的集成

元字符和文件名生成

管道和命令表

命令組合

命令替換

輸入、輸出重定向23元字符和文件名生成1.UNIX元字符(通配符)的定義*匹配任何字符串,包括空字符串;?匹配任何單個字符;[.,-,!]按照范圍、列表或不匹配等形式匹配指定的字符;\轉(zhuǎn)意符,使元字符失去其特殊的含義。例:[a-d,x,y]匹配字符a、b、c、d、x、y;z*匹配以字符z開始的任何字符串;24元字符和文件名生成x?y匹配以x開始、以y結(jié)束、中間為任何單個字符的字符串;[!Z]2.元字符作為文件擴(kuò)展名的使用例:[a-f]*匹配字符a到字符f開頭的文件名,如abc,d2,e3.c,f.dat;*z匹配以字符z結(jié)尾的任何字符串,如win.z,core.zz,a-c-5z;rc?.d匹配以rc開始、以.d結(jié)束、中間為任何單個字符的文件名,如rc0.d,匹配不為Z的單個字符。rc2.d,rcS.d;*[!o]匹配不以o結(jié)尾的文件名。25管道和命令表在shell中有兩種結(jié)構(gòu)類型:管道線和命令表。當(dāng)shell檢測到一個管道操作符時,就建立一個系統(tǒng)管道文件,這是一個先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),它允許在同一時刻對管道線上的命令或程序進(jìn)行讀和寫,即允許兩個無關(guān)的命令通過管道連接交換信息。1.管道的概念管道:是一個命令的標(biāo)準(zhǔn)輸出與另一個命令的標(biāo)準(zhǔn)輸入之間的連接,不經(jīng)過任何中間文件;管道線:是由管道操作符分隔的一個命令序列,最簡單的管道線是一個簡單命令;管道操作符:用符號“|”表示。26管道和命令表例:w|wc-lpsaux|grepftp2.命令表的概念命令表:一串管道線構(gòu)成了一個命令表,最簡單的命令表是一個管道線,一個命令表送回的值是該命令表中最后一個管道線的出口狀態(tài)。管道線分隔符:分隔命令表元素,確定管道線執(zhí)行的條件。各分隔符含義如下:;表示按順序執(zhí)行管道線;&&表示根據(jù)條件(true),執(zhí)行其后面的管道線;‖表示根據(jù)條件(false),執(zhí)行其后面的管道線;27管道和命令表&表示前面的管道線在后臺(異步)執(zhí)行。例1:四個管道線構(gòu)成一個命令表ls-l/tmp/rootw|wc-lps例2:與例1等價ls-l/tmp/root;w|wc-l;ps例3:sys-account&28命令組合命令組合有兩種形式:{命令表}和(命令表),前者只在本shell中執(zhí)行,不產(chǎn)生新的子進(jìn)程;后者要產(chǎn)生新的子進(jìn)程來執(zhí)行命令表。例1:{cdmydoc;rmjunk;}該命令表只能在當(dāng)前shell下執(zhí)行,先進(jìn)入目錄mydoc,然后執(zhí)行rm命令,執(zhí)行完畢后,當(dāng)前目錄已改變?yōu)閙ydoc。例2:(cdmydoc;rmjunk;)當(dāng)前shell要生成一個子shell進(jìn)程,由該子shell來執(zhí)行命令表。子shell完成操作后,自然消亡,而其父shell進(jìn)程的當(dāng)前路徑并沒有變化。29命令替換當(dāng)一個字符串被括在反撇號“`”中時,該字符串將作為命令被shell解釋執(zhí)行,即用命令的執(zhí)行結(jié)果替換這個字符串本身。要注意反撇號與單引號的區(qū)別。例1:$now=′date′$echo$nowdate$now=`date`$echo$now1998年10月28日星期三17時51分56秒CST例2:$count=10$count=`expr$count+1`$echo$count30輸入、輸出重定向1.使用標(biāo)準(zhǔn)改向符進(jìn)行重定向(改向)<輸入改向<<追加輸入改向>輸出改向>>追加輸出改向2.使用標(biāo)準(zhǔn)文件描述字進(jìn)行重定向(改向)在Linux系統(tǒng)中,定義了用于輸入、輸出的標(biāo)準(zhǔn)文件,其文件描述字0為進(jìn)程的標(biāo)準(zhǔn)輸入、文件描述字1為標(biāo)準(zhǔn)輸出、文件描述字2為標(biāo)準(zhǔn)錯誤輸出。3.標(biāo)準(zhǔn)錯誤輸出的改向(>、>>)格式為:31輸入、輸出重定向command2>filecommand2>>file例1:將myfile1作為sort的輸入。sort<myfile1例2:將date的輸出轉(zhuǎn)向到myfile2文件中。date>myfile2例3:將ls\|l的輸出追加到myfile3文件中。ls-l>>myfile3例4:將錯誤輸出改向到err-file文件。$myprog2>err-file例5:將標(biāo)準(zhǔn)輸出和錯誤輸出改向out文件。$myprog>out2>>out$myprog>out2>>&132第5節(jié)shell變量

Shell變量描述

用戶自定義變量

位置變量

環(huán)境變量

預(yù)定義的特殊變量

變量替換

特殊字符的引用33Shell變量描述shell實(shí)際上是基于字符串的程序設(shè)計(jì)語言,但也有變量。shell變量能夠而且只能存儲正文字符串,即它只有一種類型的變量即串變量。但從賦值的形式上看,則可以分成四種類型的變量或變量形式。變量的名字必須以字母或下劃線開頭,可以包括字母、數(shù)字和下劃線。34用戶自定義變量用戶自定義變量語法格式:name=string,賦值號“=”兩邊不允許有空白符。例:nodehost=beijing.UUCPpath=/bin:/usr/bin:/etc/bincount=10允許多個賦值操作,按從右到左的順序進(jìn)行。例:$A=$BB=abcC=″OK″$echo$A$B$CabcabcOK當(dāng)引用一個未設(shè)置的變量時,其隱含值為空。例:$echo″$mailispathofmailbox″ispathofmailbox35用戶自定義變量如果用雙引號“”將值括起來,則括起來的字符串允許出現(xiàn)空格、制表符和換行符等特殊字符,而且允許有變量替換。例1:$MAIL=/var/mail/fk$var=″$MAILispathofmailbox″$echo$var/var/mail/fkispathofmailbox例2:$str=″Thisis\nabook″$echo$strThisisabook36用戶自定義變量如果用單引號‘’將值括起來,則括起來的字符串允許出現(xiàn)空格、制表符和換行符的特殊字符,但不允許有變量替換。例3:$BOOK=″Englishbook″$MSG=′$BOOK′$echo$MSG$BOOK例4:$msg=′TodayisSunday′$echo$msgTodayisSunday37用戶自定義變量引用變量的值時,可以用花括號{}將變量名稱括起來,使變量名稱與它的后續(xù)字符分隔開,如果緊跟在變量名稱后面的字符是字母、數(shù)字或下劃線時,必須要使用花括號。例5:$str=′Thisisastring′$echo″${str}enttestofvariables″Thisisastringenttestofvariables$echo″$strenttestofvariables″testofvariables38用戶自定義變量可將變量設(shè)置為只讀形式,格式為,readonly變量名1變量名2例6:$ux=UNIX.SUN$readonlyux$ux=UNIX.SCOux:isreadonly查看只讀形式的變量,格式為readonly例7:$readonlyreadonlyux39位置變量位置變量顧名思義是與變量所在位置有關(guān)的變量,這是一種特殊的變量。當(dāng)一個shell過程被調(diào)用時,shell隱含地為它建立一系列的位置變量。這種位置變量是系統(tǒng)預(yù)定義好的,可以直接引用。如命令行的shell過程名本身被指定為位置變量$0,第一個命令參數(shù)為$1,……,第九個命令參數(shù)為$9。例:ls//bin/etc/usr/bin/dev$0$1$2$3$4$540位置變量1.內(nèi)部命令shift的作用當(dāng)位置變量個數(shù)超出9時,就不能直接引用位置大于9的位置變量了,必須用shift命令存取。每執(zhí)行一次shift命令,刪除$1位置變量,并使其他的所有位置變量向左移動一個位置。例:$0$1$2$3$4$5$6$7$8$9myprogabcdefghijshiftbcdefghijshiftcdefghijshiftdefghij41位置變量2.用set命令進(jìn)行強(qiáng)制性賦值位置變量可以使用set命令進(jìn)行強(qiáng)制性賦值。例:setSunMonTueWedThuFriSat結(jié)果$1$2$3$4$5$6$7注意:$0是不能用這種方法賦值的。42環(huán)境變量shell執(zhí)行環(huán)境由一系列環(huán)境變量組成,這些變量是由shell維護(hù)和管理的。所有這些變量都可被用戶重新設(shè)置,變量名由大寫字母或數(shù)字組成。CDPATH執(zhí)行cd命令時使用的搜索路徑;HOME用戶的home目錄;PATH尋找命令或可執(zhí)行文件的搜索路徑;PS1主命令提示符,默認(rèn)為“$”;PS2從命令提示符,默認(rèn)為“>”;TERM使用的終端類型。43預(yù)定義的特殊變量在shell中有一組特殊的變量,其變量名和變量值只有shell本身才可以設(shè)置。“$#”記錄傳遞給shell的自變量個數(shù)。例1:myprogabc則$#的值為3例2:iftest$#-lt2thenecho″twoormoreargsrequired″exitfi44預(yù)定義的特殊變量“$?”取最近一次命令執(zhí)行后的退出狀態(tài):執(zhí)行成功返回碼為0,執(zhí)行失敗返回碼為1。例:$test-rmy-file(假設(shè)my-file文件不可讀)$echo$?1“$$”記錄當(dāng)前shell的進(jìn)程號。45變量替換shell在遇到未設(shè)置的變量時,將其值作為空串處理。而在實(shí)際應(yīng)用中,對于未設(shè)置的變量,用戶可以根據(jù)需要采用不同的處理方式,這可通過變量替換來實(shí)現(xiàn)。變量替換提供了三種功能:允許替換未設(shè)置變量的隱含值;允許對未設(shè)置變量賦值;在訪問未設(shè)置變量時,提示出錯信息。格式為,${var:-word}例1:假設(shè)$PARM未設(shè)置$echo″ThevalueofPARMis${PARM:-undefined}″ThevalueofPARMisundefined$echo$PARM46變量替換例2:假設(shè)$PARM未設(shè)置$arg=${PARM:-″notdefined″}(注意:雙引號)$echo′$arg:′$arg$arg:notdefined例3:對未設(shè)置變量賦值$catuse.dsel=$1:${sel∶=main}(注意:此處的“:”為空命令)echo″Yourselectionis$sel″$grammingYgramming47變量替換注意:變量替換的這種形式不允許使用位置變量,若要使用位置變量,則必須先將位置變量賦值給一中間變量,然后再對中間變量進(jìn)行這種形式的替換。例4:將例3中的空命令用中間變量替換。$catuse.dsel=$1my-sel=${sel∶=main}echo″Yourselectionis$my-sel″$grammingYgramming48變量替換例5:測試環(huán)境變量TERM是否設(shè)置?!鏲atcheck.env:${TERM:?″theTERMvaribleshouldbeset″}注意:出錯信息以一行長為限,且輸出到標(biāo)準(zhǔn)錯誤輸出上。49特殊字符的引用在shell中所使用的許多特殊符號也可為其他目的所使用,因此當(dāng)不需要引用這些字符的特殊含義時,就必須進(jìn)行刪除。消除特殊字符的含義有3種常用的方法,分別是轉(zhuǎn)義符、單引號和雙引號。1.轉(zhuǎn)義符(\)的引用使用轉(zhuǎn)義符消除單個字符的特殊含義,即將緊跟在轉(zhuǎn)義符后面的單個字符按字符本身的實(shí)際含義解釋。例:轉(zhuǎn)義符具有續(xù)行功能$catback.shecho″E:\\c″echoHello$name50特殊字符的引用$back.shE:johnHellojohn2.單引號(‘’)的引用使用單引號消除被括在單引號中的所有特殊字符的含義,即單引號表示內(nèi)容照原樣不動。例1:$echo′typea$*please′typea$*please例2:在指定的目錄中,查找名字為*.zh或$.sh文件。$cattest.shgrep′*.zh|$.sh′$151特殊字符的引用3.雙引號(“”)的引用使用雙引號能消除被括在雙引號中的大部分特殊字符的含義,不能消除的字符有:$、`、″、\。例1:$echo″Typea\$*,please″Typea$*,please例2:vdate=″`date`isthesystemmaintenancetime!″例3:$catshare-filemkdir/tmp/fkchmod755/tmp/fkcp″$@″/tmp/fkchmod777/tmp/fk/*52特殊字符的引用4.特殊字符串引用的例外引用雙引號、單引號和轉(zhuǎn)意符都不能消除對echo命令有特殊功能的控制字串的特殊含義。這些控制字串是:\b退格\c顯示后不換行\f在終端上屏幕的開始處顯示\n換行\r回車\t制表符\v垂直制表符\反斜杠53第6節(jié)shell的控制結(jié)構(gòu)

條件與test命令

If結(jié)構(gòu)

Case結(jié)構(gòu)

For結(jié)構(gòu)

While結(jié)構(gòu)

Until結(jié)構(gòu)

循環(huán)體中其他命令

函數(shù)的定義與使用54條件與test命令在程序設(shè)計(jì)語言中,作出決策的結(jié)構(gòu)稱為條件。在高級語言中決策的作出是依賴于基本運(yùn)算的結(jié)果;在shell語言中,作出決策所依賴的條件是所執(zhí)行命令的“出口狀態(tài)”。當(dāng)shell命令或程序執(zhí)行成功時,它返回一個“零”出口狀態(tài)(即$?為零);如果執(zhí)行的命令或程序出錯時,則返回一個“非零”的出口狀態(tài)(即$?不為零)。除了一般命令的出口狀態(tài)外,UNIX還提供了兩個命令true和false的出口狀態(tài)。true的出口狀態(tài)為零;而false的出口狀態(tài)為非零。shell將true和false命令作為恒真和恒假條件使用。55條件與test命令例:判斷所給出的參數(shù)是否為一個目錄?!鏲atcheck.dirtest-d$1&&echo″$1isadictory″&&exit0echo″$1isnotadictroy″exit1在上例中,使用了exit命令。它是一個shell的內(nèi)部命令,用于終止shell程序的執(zhí)行。該命令可帶一個定義出口狀態(tài)值的自變量。例:exit(0):終止程序的執(zhí)行,并返回零值;exit(1)或exit(x):終止程序的執(zhí)行,并返回非零值;將命令返回零出口狀態(tài)稱為返回“真值”;將命令返回非零出口狀態(tài)稱為返回“假值”。56條件與test命令1.test命令test命令是shell程序設(shè)計(jì)的條件判斷中最常用的測試命令,它有兩種等價的格式:testexpression或[expression](注意:[]中的空格)其中expression就是要測試的條件。如果test計(jì)算expression的結(jié)果為真,則返回“零”出口狀態(tài),否則返回“非零”出口狀態(tài)。test命令可用于對字符串、整數(shù)及文件進(jìn)行各類測試。57條件與test命令2.test字符串測試表達(dá)式例1:兩個字符串進(jìn)行比較$user=smith$test″$user″=smith$echo$?0$test″$user″=tom$echo$?158條件與test命令例2:帶有空格的字符串比較$month=″January″$test″$month″=January$echo$?1$test$month=January$echo$?0注意:shell在處理變量時,遇到有雙引號將保留其內(nèi)容,而省略雙引號時,將濾去空格。59條件與test命令例3:帶有空格的字符串比較$a=″testingstring″$test″$a″=″testingstring″$echo$?0$test$a=″testingstring″test:unknownoperatorstringshell處理變量$a時,將其進(jìn)行變量替換,然后將結(jié)果(testingstring)傳遞給test,而test將string作為操作符來處理,因此出錯。60條件與test命令例4:帶有空串(或未設(shè)置的字符串比較)$name=$test″$name″=smith$echo$?1$test$name=smithtest:argumentexpectedshell處理變量$name時,雙引號將其括起的內(nèi)容作為一個“位置持有者”來保留,并把該值傳遞給test,保證處理的正常執(zhí)行。61條件與test命令例5:帶有空串的字符串比較$blanks=″″$test$blanks$echo$?1$test″$blanks″$echo$?0shell處理變量$blanks時,將空格濾去,使其變?yōu)榭沾畟鬟f給test;而雙引號保留“位置持有者”的位置,其值為一個空格(空白符),傳遞給test。62條件與test命令例6:帶有算符的字符串比較$symvar=″=″$echo″$symvar″=$test-z″$symvar″test:argumentexpected出錯的原因是“=”運(yùn)算符比“-z”運(yùn)算符的優(yōu)先級要高,因此,test命令期望在等號之后要有一個自變量。為避免上述問題發(fā)生,可用下面命令形式替換:$testx″$symvar″=x$echo$?163條件與test命令3.使用test測試字符串時要注意的問題(1)向test傳遞的各自變量之間必須有空白字符,如果“=”與任一自變量之間沒有空白字符就會產(chǎn)生錯誤。(2)在使用變量的值替換的自變量上,用雙引號括起來十分必要,以保證test在變量的值為空時也能接收到該自變量,這是一種良好的shell程序設(shè)計(jì)風(fēng)格。(3)在test命令的測試中,空格和引號是shell程序設(shè)計(jì)中經(jīng)常發(fā)生錯誤的焦點(diǎn),要特別引起注意。(4)test命令對它的自變量非常講究,在比較的串中出現(xiàn)運(yùn)算符時,要考慮到運(yùn)算符優(yōu)先級的問題。64條件與test命令4.test命令可用于整數(shù)比較首先要搞清楚整數(shù)比較的兩個概念:shell并不區(qū)分放在shell變量中的值的類型,就變量本身而言,它存放的僅僅是一組字符串,即shell只有一種類型的變量——串變量;當(dāng)使用整數(shù)比較操作符時,是test命令來解釋存放在變量中的整數(shù)值,而不是shell。命令格式為,test整數(shù)測試表達(dá)式65條件與test命令例1:$x1=″005″$x2=″10″$test″$x1″=5$echo$?1例2:$test″$x1″-eq5$echo$?0例3:$test″$x2″-eq10$echo$?066條件與test命令5.test用于文件的測試test可用于文件各種特性的檢查。這些文件的操作符自然是一原操作符,意味著它們要求其后跟隨一個自變量。在所有的情況中,這個自變量是一個文件或目錄名。常用的文件測試表達(dá)式示例如下:例1:檢查指定的文件是否存在并且可讀test-f/usr/fk/message例2:檢查指定的文件是否為目錄test-d/usr/src/local/sendmail例3:檢查指定的出錯文件是否為空,如不空則列出該文件的內(nèi)容test-s$errfile&&{echo″Errorsfound:″;\cat$errfile}67條件與test命令6.表達(dá)式的邏輯運(yùn)算在實(shí)際應(yīng)用中常需要將多個表達(dá)式用邏輯運(yùn)算符組合起來,構(gòu)成比較復(fù)雜的條件。邏輯運(yùn)算符包括:!:邏輯非單目運(yùn)算符,可放置在任何其他test表達(dá)式之前,求得表達(dá)式運(yùn)算結(jié)果的非值。-a:邏輯與運(yùn)算符,執(zhí)行兩個表達(dá)式的邏輯與運(yùn)算,并且僅當(dāng)兩者都為真時,才返回真值。-o:邏輯或運(yùn)算符,執(zhí)行兩個表達(dá)式的邏輯或運(yùn)算,并只要當(dāng)兩者之一為真時,就返回真值。邏輯運(yùn)算符優(yōu)先級(由高到低)的排列順序如下:()!-a-o68條件與test命令邏輯運(yùn)算符優(yōu)先級要比字符串操作符、數(shù)字比較操作符、文件操作符的優(yōu)先級低。例1:當(dāng)指定的文件不可讀時為真。test!-r/usr/fk/message例2:當(dāng)指定的文件均存在,且message為可讀、$mailfile指定的文件為普通文件時,返回真。test-r/usr/fk/message-a-f″$mailfile″例3:當(dāng)變量值大于等于0并且小于10時為真。test″$count″-ge0-a″$count″-lt10例4:當(dāng)變量$a等于0或者$b大于5,并且$c小于等于8時為真。test\(″$a″-eq0-o″$b″-gt5\)-a″$c″-le869If結(jié)構(gòu)1.if的簡單結(jié)構(gòu)格式為,mandthencommandcommand...fi70If結(jié)構(gòu)2.if的完整結(jié)構(gòu)格式為,mandthencommandcommand...elsecommandcommand...fi71If結(jié)構(gòu)3.if的連用結(jié)構(gòu)格式1mandthenelsecommandsmandthenelsemandthenficommands…commands...fifi72If結(jié)構(gòu)格式2mandthenmandcommandsthencommandselif…mandsthenelsecommandscommandsfi73Case結(jié)構(gòu)格式為,casevalueinpattern1)command...command;;pattern2)command...command;;...patternn)command...command;;esac74For結(jié)構(gòu)格式為,forvariableinarg1arg2...argndocommand...commanddone75While結(jié)構(gòu)格式為,manddocommand...commanddone76Until結(jié)構(gòu)格式為,manddocommand...commanddone77循環(huán)體中其它命令1.break命令格式為,break或breaknbreak是shell的內(nèi)部命令,用于在循環(huán)體中根據(jù)命令運(yùn)行的返回條件,直接終止循環(huán)體內(nèi)命令的執(zhí)行。當(dāng)執(zhí)行break命令時,控制流從循環(huán)體中轉(zhuǎn)移到done之后的第一條命令上。當(dāng)執(zhí)行breakn命令時,則終止最內(nèi)層的n個循環(huán)的執(zhí)行。2.continue命令格式為,continue或continuen78循環(huán)體中其它命令continue是shell的內(nèi)部命令,用于在循環(huán)體中根據(jù)命令運(yùn)行的返回條件,直接進(jìn)入下一次循環(huán)命令的執(zhí)行。當(dāng)執(zhí)行continue命令時,控制流直接轉(zhuǎn)到本循環(huán)體中第一條命令上。當(dāng)執(zhí)行continuen命令時,則跳過最里層的n次循環(huán)體的執(zhí)行,即開始第n個(從內(nèi)向外數(shù))循環(huán)的下一個循環(huán)過程。3.循環(huán)中的輸入輸出改向?qū)φ麄€循環(huán)命令也可實(shí)施shell命令的輸入輸出改向。循環(huán)輸入的改向?qū)⒆饔糜谘h(huán)體中從標(biāo)準(zhǔn)輸入讀數(shù)據(jù)的所有命令;而循環(huán)輸出改向?qū)⒆饔糜谘h(huán)體中向標(biāo)準(zhǔn)輸出寫數(shù)據(jù)的所有命令。在循環(huán)體內(nèi)也可以進(jìn)行輸入輸出改向,且這種改向獨(dú)立于整個循環(huán)體命令的輸入輸出改向。79循環(huán)體中其它命令例:whiletest″$count″-lt20do...echo″error:$count″...echo″right:$count″>/dev/tty...done2>error.out80循環(huán)體中其它命令4.循環(huán)體與管道循環(huán)命令也能通過管道與其他的shell命令聯(lián)接在一起使用。一個命令的輸出通過管道可以作為循環(huán)命令的輸入,而整個循環(huán)命令的輸出也可以通過管道作為另一個命令的輸入。例:$foriinabcd>do>echo$i>done|wc-l481函數(shù)的定義與使用函數(shù)實(shí)際上是由若干shell命令組成,因此它與shell的命令文件形式上是相似的。不同的只是shell函數(shù)常駐于內(nèi)存之中。它們不再是一個單獨(dú)的進(jìn)程,而是成了shell的一部分。格式為,F(xiàn)unctionName(){command…command}82函數(shù)的定義與使用函數(shù)僅存在于定義它的shell環(huán)境中,不能把它們傳遞給子shell。函數(shù)是在當(dāng)前shell中被執(zhí)行的,在函數(shù)體中變量值和當(dāng)前工作目錄的改變,將影響當(dāng)前shell的運(yùn)行環(huán)境。函數(shù)一旦定義就被存入內(nèi)存,shell執(zhí)行函數(shù)時不需要在磁盤中進(jìn)行查找,所以執(zhí)行速度要比把函數(shù)中的命令放入到一個文件中的執(zhí)行要快。使用函數(shù)時,命令行中列在函數(shù)名后的自變量傳遞給函數(shù)體中的位置參數(shù)。函數(shù)執(zhí)行返回時也有一個出口狀態(tài)。函數(shù)體內(nèi)執(zhí)行exit命令將結(jié)束函數(shù)的執(zhí)行,同時也結(jié)束調(diào)用函數(shù)的shell程序的運(yùn)行。而return命令用于結(jié)束函數(shù)的執(zhí)行,如省略return時,則以最后一條命令的出口狀態(tài)作為函數(shù)的出口狀態(tài)。83函數(shù)的定義與使用例:#ThetestcodesforfunctiondefinitionGetYesOrNo(){whileecho″$*(Y/N)?\c″>&2doreadreplyRestDatacase″$reply″in[yY])return0;;[nN])return1;;*)echo″PleaseenterYorN!″>&2;;esac}done執(zhí)行$GetYesOrNo″Doyouwishtocontinue″||exit顯示Doyouwishtocontinue(Y/N)?84第7節(jié)shell的運(yùn)行環(huán)境

局部變量

全局變量

局部變量和全局變量作用域

程序調(diào)試

Shell程序的應(yīng)用85局部變量當(dāng)用戶注冊之后,用戶就擁有了注冊shell的運(yùn)行環(huán)境,其運(yùn)行環(huán)境主要由shell變量值決定。注冊shell在接受到用戶輸入的命令(非內(nèi)部命令)后,通常派生出一個子shell,由此子shell負(fù)責(zé)解釋執(zhí)行該命令。子shell有自己的運(yùn)行環(huán)境和局部變量,局部變量僅在特定的環(huán)境下才能使用。shell的運(yùn)行環(huán)境是可以改變的,但子shell不能存取由父shell設(shè)置的局部變量,也不能改變父shell的變量值。86局部變量例1:$catvar-testecho:$x:$x=100$var-test::例2:$catvar-test2x=60echo:$x:$x=10$var-test2:60:$echo$x1087全局變量全局變量是一種特殊的變量,可以被任何運(yùn)行的子shell來引用。全局變量通過export命令來定義,格式如下:exportvariables其中variables是定義全局變量的變量表名。一旦變量被定義為全局變量,則對于以后的所有子shell來說這些都是全局變量。子shell中無法改變?nèi)肿兞康闹?。若在子shell中改變?nèi)肿兞康闹担瑢?shí)際是對全局變量的副本進(jìn)行更改,不影響全局變量值。子shell中局部變量的使用優(yōu)先于全局變量。88全局變量例:$exportg-var$g-var=″GLOBAL″$cattest-varexportg-varl-varg-var=″sub-shell:g-var″l-var=″sub-shell:l-var″echo$g-var$l-var$test-varsub-shell:g-varsub-shell:l-var$echo$g-var:$l-var:GLOBAL::$89局部變量和全局變量作用域任何沒有用export命令定義過的變量是局部變量,子shell不能存取父shell的局部變量。子shell中可以存取和修改父shell的全局變量,但這種修改對于父shell全局變量沒有任何影響。在子shell中用export命令定義的全局變量和對此變量的修改對父shell變量沒有影響。全局變量保持它的全局性,不僅能直接傳遞給它的子shell,而且子shell還能將它傳遞給子shell的子shell。在對變量賦值之前和之后的任何時候可以將該變量轉(zhuǎn)換成全局變量。90程序調(diào)試shell提供了多種工具以便在調(diào)試shell程序時使用,這些工具允許觀察一個shell程序的執(zhí)行,還允許觀察一個程序在不做任何實(shí)際處理的情況下是如何被“執(zhí)行”的。提供的測試方式有:1.shell程序的詳細(xì)跟蹤shell提供的詳細(xì)跟蹤特性允許用戶觀察一個shell程序的讀入和執(zhí)行,如果在讀入命令行時發(fā)現(xiàn)語法錯誤,則終止程序的執(zhí)行。命令行被讀入后,shell按讀入時的形式在標(biāo)準(zhǔn)錯誤輸出中顯示該命令行,然后執(zhí)行命令行。詳細(xì)跟蹤shell程序的執(zhí)行有兩種方式:整個程序的詳細(xì)跟蹤和局部程序的詳細(xì)跟蹤。91程序調(diào)試整個程序的跟蹤執(zhí)行格式:sh-v文件名用來實(shí)現(xiàn)對整個文件的腳本進(jìn)行跟蹤。局部程序的跟蹤執(zhí)行格式:set-v——設(shè)置跟蹤標(biāo)志set+v——關(guān)閉跟蹤標(biāo)志用來實(shí)現(xiàn)對文件中的部分腳本進(jìn)行跟蹤。92程序調(diào)試?yán)骸鏲attraceddateecho$PATH|wc-c$traced1998年11月05日星期四17時29分59秒CST45$sh-vtraceddate1998年11月05日星期四17時30分08秒CSTecho$PATH|wc–c45邊解釋,邊執(zhí)行93程序調(diào)試2.shell程序的跟蹤執(zhí)行此功能允許用戶觀察一個shell程序的執(zhí)行,它使命令行在執(zhí)行前完成所有替換之后,在標(biāo)準(zhǔn)錯誤輸出中顯示每一個被替換后的命令行,并且在行前加上前綴符號“+”(但變量賦值語句不加“+”符號),然后執(zhí)行命令。對shell程序的跟蹤執(zhí)行也有兩種方式:整個程序的跟蹤執(zhí)行和局部程序的跟蹤執(zhí)行。整個程序的跟蹤執(zhí)行格式為,sh-x文件名用來實(shí)現(xiàn)對整個文件腳本的跟蹤執(zhí)行。局部程序的跟蹤執(zhí)行格式為,set-x——設(shè)置跟蹤標(biāo)志set+x——關(guān)閉跟蹤標(biāo)志94程序調(diào)試用來實(shí)現(xiàn)對文件中部分腳本的跟蹤執(zhí)行。例:$cattraceddateecho$PATH|wc-c$sh-xtraced+date1998年11月05日星期四17時30分08秒CST+echo/bin:/usr/bin:/usr/fk/bin/bin:/usr/bin:/usr/fk/bin+wc-c2595程序調(diào)試3.詳細(xì)跟蹤與跟蹤執(zhí)行的組合整個程序的跟蹤執(zhí)行格式為,sh-vx文件名局部程序的跟蹤執(zhí)行格式為,set-vx——設(shè)置跟蹤標(biāo)志set+vx——關(guān)閉跟蹤標(biāo)志詳細(xì)跟蹤與跟蹤執(zhí)行的區(qū)別在于在執(zhí)行命令行之前,詳細(xì)跟蹤打印出命令行的原始內(nèi)容,而跟蹤執(zhí)行卻打印出經(jīng)過替換后的命令行內(nèi)容,循環(huán)結(jié)構(gòu)和管道線在兩種跟蹤方式中是根本不同的。由于shell對這些結(jié)構(gòu)只讀取一次,因此,詳細(xì)跟蹤方式也僅顯示它們一次。但這類結(jié)構(gòu)的命令行可能要被重復(fù)執(zhí)行多次,所以,跟蹤執(zhí)行方式就可能將同樣的命令行顯示一次以上。96程序調(diào)試4.非執(zhí)行跟蹤shell的非執(zhí)行任選項(xiàng)提供的功能允許用戶觀察一個shell程序,而程序中的命令行不被執(zhí)行。非執(zhí)行通常與詳細(xì)跟蹤結(jié)合使用,查看在不實(shí)際執(zhí)行一個shell程序時,程序是如何被“執(zhí)行”的。其格式為,sh-n文件名或set-n97程序調(diào)試5.未置變量退出跟蹤shell的未置變量退出特性允許對所有的變量進(jìn)行檢查,如果引用了一個未賦值的變量就終止shell程序執(zhí)行。shell通常允許未置變量的使用,在此種情況下,變量的值為空。但如果設(shè)置了未置變量退出的任選項(xiàng),則一旦使用了未置的變量就顯示出錯信息,并終止程序的運(yùn)行。其格式為,sh-u文件名或set-u——設(shè)置標(biāo)志set+u——清除標(biāo)志98程序調(diào)試6.立即退出跟蹤shell的立即退出特性允許在程序內(nèi)的任何命令以非零狀態(tài)退出時,立即終止程序的運(yùn)行。其格式為,sh-e文件名或set-e——設(shè)置標(biāo)志set+e——清除標(biāo)志99Shell程序的應(yīng)用1.shell程序的定義若一個文件包含了一串簡單命令串時,稱為命令文件;若一個文件包含了一組更為復(fù)雜的命令組合(常常使用了shell的條件命令、控制結(jié)構(gòu)和其他高級特性)時,就稱之為shell程序(或稱shell過程)。通常情況下,兩者的稱呼并沒有明確的區(qū)別。在shell程序設(shè)計(jì)語言里的基本操作是Linux系統(tǒng)命令,它是Linux系統(tǒng)中最有生氣的部分,而且對于Linux系統(tǒng)的使用極為重要。100Shell程序的應(yīng)用2.何時使用shell程序設(shè)計(jì)語言當(dāng)一個問題的解決方法需要使用多個Linux系統(tǒng)的標(biāo)準(zhǔn)命令時,可使用shell命令文件。如果處理的問題比較復(fù)雜,可以使用shell程序設(shè)計(jì)語言,即在命令文件中定義各種參數(shù)和變量,使用shell的條件命令、控制結(jié)構(gòu)和其他高級特性。101第8節(jié)shell應(yīng)用實(shí)例下面這段程序取自/etc/rc.d/rc.sysinit文件中的一部分,/etc/rc.d/rc.sysinit文件是Linux系統(tǒng)啟動過程中需要執(zhí)行的shell程序。這段程序的功能主要是配置網(wǎng)絡(luò)環(huán)境、檢查文件系統(tǒng)和加載應(yīng)用模塊。要注意,在shell程序中注釋語句是以#開頭,但以#!開頭的語句并不是注釋語句。如果想執(zhí)行該程序,可以用一般用戶登錄系統(tǒng)后,直接執(zhí)行/etc/rc.d/rc.sysinit。102第8節(jié)shell應(yīng)用實(shí)例#第一條語句先指定本shell程序采用哪個shell執(zhí)行。#!/bin/sh——此處#不可缺少,#表示后跟shell程序#以#開始的語句是注釋行。#/etc/rc.d/rc.sysinit-runonceatboottime##TakeninpartfromMiquelvanSmoorenburg′sbcheckrc.##下面語句是定義變量PATH,并把PATH變量聲明為全局變量。#SetthepathPATH=/bin:/sbin:/usr/bin:/usr/sbinexportPATH103第8節(jié)shell應(yīng)用實(shí)例#下面命令讀取配置數(shù)據(jù),這里用到一個簡單的IF語句。#判斷/etc/sysconfig/network文件存在否,如果該文件存在,就執(zhí)行它。#否則,給NETWORKING變量賦值,給HOSTNAME變量賦值。#Readinconfigdata.if[-f/etc/sysconfig/network];then./etc/sysconfig/networkelseNETWORKING=noHOSTNAME=localhostfi104第8節(jié)shell應(yīng)用實(shí)例#下面語句的功能是啟用交換,執(zhí)行shell命令swapon。#Startupswapping.echo″Activatingswappartitions″swapon\|a#以下語句設(shè)置主機(jī)名。#下面語句引用hostname變量,執(zhí)行hostname命令。#Setthehostname.hostname${HOSTNAME}echohostname:`hostname`105第8節(jié)shell應(yīng)用實(shí)例#下面語句設(shè)置NIS域名,其中引用$NISDOMAIN變量,執(zhí)行shell命令domainname。#SettheNISif[-n″$NISDOMAIN″];thendomainname$NISDOMAINelsedomainname″″fi#下面是一段簡單的if語句,判斷/fsckoptions文件是否存在,#并定義fsckoptions變量。if[-f/fsckoptions];thenfsckoptions=`cat/fsckoptions`elsefsckoptions=′′fi106第8節(jié)shell應(yīng)用實(shí)例#下面是一段簡單的if語句,判斷/fastboot文件是否不存在。#其中,引用fsckoptions變量,執(zhí)行shell語句fsck。#并引用系統(tǒng)變量$?,定義變量rc,獲取上一個shell語句的執(zhí)行結(jié)果。if[!-f/fastboot];thenecho″Checkingrootfilesystems.″fsck-V-a$fsckoptions/rc=$?#以下這段語句是檢查文件系統(tǒng)的執(zhí)行結(jié)果,#如果$rc大于1,說明文件系統(tǒng)有嚴(yán)重問題,并顯示信息。#其中,給環(huán)境變量PS1賦值,執(zhí)行shell命令sulogin,#執(zhí)行shell命令umounta,執(zhí)行shell命令reboot。#Ablems.if[$rc-gt1];thenechoechoecho″***Anerroroccurredduringthefilesystemcheck.″echo″***Droppingyoutoashell;thesystemwillreboot″echo″***whenyouleavetheshell.″107第8節(jié)shell應(yīng)用實(shí)例PS1=″(Repairfilesystem)#″;exportPS1suloginecho″Unmountingfilesystems″umountamount-n-oremount,ro/echo″Agress.″reboot#下面語句是嵌套的復(fù)合條件if語句,執(zhí)行shell命令quotacheckelif[″$rc″=″1″-a-x/sbin/quotacheck];thenecho″Checkingrootfilesystemquotas″/sbin/quotacheck-v/fifi108第8節(jié)shell應(yīng)用實(shí)例#下面語句對根系統(tǒng)實(shí)行磁盤空間限定,執(zhí)行shell命令quotaon。if[-x/sbin/quotaon];thenecho″Turningonuserandgroupquotasforrootfilesystem″/sbin/quotaon/fi#下面命令是設(shè)置PNP,首先檢查參數(shù),執(zhí)行shell命令mount。#在if語句中采用輸出重定向,定義變量PNP。#checkforargumentsc/proc/procifgrep-inopnp/proc/cmdline>/dev/null;thenPNP=elsePNP=yesfi109第8節(jié)shell應(yīng)用實(shí)例#以下語句設(shè)置PN

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論