




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第5章Shell編程基礎5.1Shell腳本的第一行“#!”(Shebang)#!(Shebang)是一個由井號‘#’和嘆號‘!’構成的字符序列。它是出現(xiàn)在Shell腳本文件第一行的前兩個字符。腳本中的#!行(第一行)用于指示一個解釋程序。#!行的語法格式類似如下所示:#!INTERPRETER[OPTION]…5.2Shell中的注釋Shell腳本中,井號‘#’是注釋標識符。如果腳本的某行含有#或以#開頭(除了$#),那么這一行在#之后的所有內容都將被解釋程序忽略,#之后的這些內容被稱為注釋。Shell腳本的注釋用于解釋腳本及其相關語句的用途和含義,使這些腳本源代碼更容易被別人或自己(很長一段時間之后的自己)讀懂和理解,使以后對腳本的維護和更新更容易。我們來看下面這個腳本:$catseeDate_IP_Hostname.sh#!/bin/bash#ASimpleShellScriptToGetLinuxDate&Hostname&NetworkInformation#LiuYantao-2013-10-07echo"Currentdate:$(date)@$(hostname)"echo"Networkconfiguration"/sbin/ifconfig–a5.3實例:如何設置腳本的權限和執(zhí)行腳本在你運行一個Shell腳本之前,你要確保你的Shell腳本文件具有可執(zhí)行的權限,否則當你直接運行腳本時,會得到“Permissiondenied”的錯誤信息。類似如下所示:$./multicomments.sh-bash:./multicomments.sh:Permissiondenied如果遇到上述錯誤,你就需要給腳本文件添加可執(zhí)行的權限。使用在第3.3.2章節(jié)中介紹的chmod命令給文件添加執(zhí)行權限:$chmodu+x./multicomments.sh如果你想給所有用戶執(zhí)行此腳本的權限,則使用如下的命令:$chmod+x./multicomments.sh運行一個Shell腳本,使用絕對路徑或相對路徑兩種方式都可以。5.4Shell變量進階5.4.1Bash中的參數(shù)擴展參數(shù)是一個存儲數(shù)值的實體,并由名稱、數(shù)字或特定符號所引用。被名稱引用的參數(shù)稱作變量。被數(shù)字引用的參數(shù)稱作位置參數(shù)。被特定符號引用的參數(shù)具有特殊的含義和用途,被做為Bash的特殊內部變量引用。參數(shù)擴展是從引用的實體取值的過程,就像擴展變量打印它的值。5.4.1Bash中的參數(shù)擴展字符“$”會引導參數(shù)擴展。將要擴展的參數(shù)名或符號可以放在大括號中。大括號雖然是可選的,但卻可以保護待擴展的變量,使得緊跟在大括號后面的內容不會被擴展。我們通過下面的列表來了解一下參數(shù)擴展的各種形式:基本的參數(shù)擴展:$PARAMETER${PARAMETER}如果參數(shù)名后面還緊連著其它字符,這時使用大括號{}是必須的,否則緊接在參數(shù)名后面的字符串會被解釋為參數(shù)名的一部分。例如我們想打印一個單詞后跟字母‘s’:$WORD=car$echo$WORDs
$echo${WORD}scars5.4.1Bash中的參數(shù)擴展另外,對于訪問$9之后的位置參數(shù)也同樣需要使用大括號(關于位置參數(shù)的詳細內容將在5.4.3節(jié)中介紹),比如下面的示例:$echo"Argument1is:$1"$echo"Argument10is:${10}"注意:參數(shù)名是大小寫敏感的。間接參數(shù)擴展:${!PARAMETER}上述語句中,被引用的參數(shù)不是PARAMETER自身,而是PARAMETER的值。比如,如果參數(shù)PARAMETER的值是“TEMP”,則${!PARAMETER}將擴展為參數(shù)TEMP的值.5.4.1Bash中的參數(shù)擴展大小寫修改(Bash4.0的新特性):${PARAMETER^}${PARAMETER^^}${PARAMETER,}${PARAMETER,,}${PARAMETER~}${PARAMETER~~}上述語句中的這些擴展操作符修改參數(shù)值中的字母的大小寫。操作符‘^’將參數(shù)值得第一個字符改為大寫,操作符‘,’將參數(shù)值的第一個字符改為小寫。當使用雙重模式(^^和,,)時,參數(shù)值得所有字符都將被轉換。5.4.1Bash中的參數(shù)擴展變量名擴展:${!PREFIX*}${!PREFIX@}這種參數(shù)擴展將列出以字符串PREFIX開頭的所有變量名。默認情況下,列出的這些變量名用空格分隔。5.4.1Bash中的參數(shù)擴展字符串移除:${PARAMETER#PATTERN}${PARAMETER##PATTERN}${PARAMETER%PATTERN}${PARAMETER%%PATTERN}這種參數(shù)擴展可以只擴展參數(shù)值的一部分,用指定的模式來描述從參數(shù)值字符串中移除的內容。上述的語法格式中,前兩個語句用于移除從參數(shù)值的開頭匹配指定模式的字符串,而后兩個語句與之相反,用于從參數(shù)值的末尾匹配指定模式的字符串。操作符‘#’和‘%’表示將移除匹配指定模式的最短文本,而操作符‘##’和‘%%’表示移除匹配指定模式的最長文本。5.4.1Bash中的參數(shù)擴展字符串搜索與替換:${PARAMETER/PATTERN/STRING}${PARAMETER//PATTERN/STRING}${PARAMETER/PATTERN}${PARAMETER//PATTERN}這種參數(shù)擴展可以替換參數(shù)值中匹配指定模式的子字符串。操作符‘/’表示只替換一個匹配的字符串,而操作符‘//’表示替換所有匹配的字符串。如果沒有指定替換字符串STRING,那么匹配的內容將被替換為空字符串,即被刪除。5.4.1Bash中的參數(shù)擴展求字符串長度:${#PARAMETER}此參數(shù)擴展格式將得到參數(shù)值的長度:$MYSTRING="HelloWorld"
$echo${#MYSTRING}115.4.1Bash中的參數(shù)擴展子字符串擴展:${PARAMETER:OFFSET}${PARAMETER:OFFSET:LENGTH}這種參數(shù)擴展格式將擴展參數(shù)值的一部分,從指定的位置開始截取指定的長度的字符串,如果省略LENGTH,將截取到參數(shù)值的末尾。5.4.1Bash中的參數(shù)擴展使用默認值:${PARAMETER:-WORD}${PARAMETER-WORD}如果參數(shù)PARAMETER是未定義,或為null時,這種模式會擴展WORD,否則將擴展參數(shù)PARAMETER。如果在PARAMETER和WORD之間略去了符號‘:’,即上述語法中的第二種格式,則只有參數(shù)PARAMETER是未定義時,才會使用WORD。5.4.1Bash中的參數(shù)擴展指定默認值:${PARAMETER:=WORD}${PARAMETER=WORD}這種模式與使用默認值的模式類似,但其區(qū)別在于,此種模式不僅擴展WORD,還將WORD賦值給參數(shù)PARAMETER,做為PARAMETER的值。5.4.1Bash中的參數(shù)擴展使用替代值:${PARAMETER:+WORD}${PARAMETER+WORD}如果參數(shù)PARAMETER是未定義,或其值為空時,這種模式將不擴展任何內容。如果參數(shù)PARAMETER是定義的,且其值不為空,這種模式將擴展WORD,而不是擴展為參數(shù)PARAMETER的值。5.4.2Bash的內部變量Bash的內部變量會影響B(tài)ash腳本的行為。在本節(jié)中我們將介紹幾個比較常用的Bash內部變量:$BASH變量:用于引用bash實例的全路徑名$HOME變量:當前用戶的home目錄$IFS變量:IFS是內部字段分隔符的縮寫$OSTYPE變量:操作系統(tǒng)的類型$SECONDS變量:腳本已經運行的秒數(shù)$TMOUT變量:如果$TMOUT變量被指定了一個非零的值,此值就會被bash的內部命令read作為默認的超時秒數(shù)。在一個交互式的Shell中,$TMOUT的值被作為命令行提示符等待輸入的秒數(shù),如果在指定的秒數(shù)內沒有輸入,Bash將自動被終結$UID變量:當前用戶的賬號標識碼(ID號),與/etc/passwd中記錄的相同5.4.3Bash中的位置參數(shù)和特殊參數(shù)Bash中的位置參數(shù)是由除0以外的一個或多個數(shù)字表示的參數(shù)。位置參數(shù)是當Shell或Shell的函數(shù)被引用時由Shell或Shell函數(shù)的參數(shù)賦值,并且可以使用Bash的內部命令set來重新賦值。位置參數(shù)N可以被引用為${N},或當N只含有一個數(shù)字時被引用為$N:$set123fourfivesix789ten$echo"$1$2$3$4$5$6$7$8$9${10}"123fourfivesix789ten位置參數(shù)不能通過賦值語句來賦值,而只能通過Bash的內部命令set和shift來設置和取消它們。當Shell函數(shù)運行時,位置參數(shù)會被臨時地替換。5.4.3Bash中的位置參數(shù)和特殊參數(shù)Bash對一些參數(shù)的處理比較特殊。這些參數(shù)只能被引用,但不能修改它們的值。這些特殊參數(shù)分別是*、@、#、?、-、$、!、0和_。特殊參數(shù)*,將擴展為從1開始的所有位置參數(shù)。如果擴展發(fā)生在雙引號內,即“$*”,則擴展為包含每個參數(shù)值的單詞,每個參數(shù)值用特殊變量IFS的第一個字符分隔。也就是說,“$*”等價于“$1c$2c…”,其中,c是特殊變量IFS的第一個字符。如果變量IFS沒有定義,則參數(shù)之間默認用空格分隔。若果IFS為空,則參數(shù)直接相連,中間沒有分隔。5.4.3Bash中的位置參數(shù)和特殊參數(shù)特殊參數(shù)@,也將擴展為從1開始的所有位置參數(shù)。但當它的擴展發(fā)生在雙引號內時,每個參數(shù)都擴展為分隔的單詞。也就是說,“$@”等價于“$1”“$2”…。參數(shù)@與*之間的區(qū)別將在for循環(huán)的調用中明顯地顯現(xiàn)出來。特殊參數(shù)#,將擴展為位置參數(shù)的個數(shù),用十進制表示。特殊參數(shù)?,將擴展為最近一個在前臺執(zhí)行的命令的退出狀態(tài)。可以使用它來檢查你的Shell腳本是否已成功地執(zhí)行,通常退出狀態(tài)0表示命令已經沒有任何錯誤的結束運行。比如,我們創(chuàng)建一個文件,并使用ls命令列出這個文件,這些命令成功執(zhí)行的話,則退出狀態(tài)將是0,否則將是其它數(shù)值。5.4.3Bash中的位置參數(shù)和特殊參數(shù)特殊參數(shù)-,將擴展為當前的選項標志。這些選項是在調用時、或由內部命令set指定,或由Shell自身指定。特殊參數(shù)$,將擴展為當前Shell的進程號。在一個子Shell中,它擴展為調用Shell的進程號,而不是子Shell的。如下所示,打印當前Shell的進程號。特殊參數(shù)!,將擴展為最近一次執(zhí)行的后臺命令的進程號。特殊參數(shù)0,將擴展為Shell或Shell腳本的名稱。它是在Shell初始化時設置。如果Bash調用時帶有腳本文件作為參數(shù),$0就設置為腳本的文件名。特殊參數(shù)_,在Shell啟動時,它被設為開始運行的Shell或Shell腳本的路徑。隨后,擴展為前一個命令的最后一個參數(shù)。5.4.4實例:使用declare指定變量的類型declare命令是Bash的內部命令,用于聲明變量和修改變量的屬性。它與Bash的另一個內部命令typeset的用法和用途完全相同。如果直接使用declare命令,不指定變量名,將顯示所有變量的值。使用-r選項,declare命令將把指定的變量定義為只讀變量,這些變量將不能再被賦予新值或被清除。使用-i選項,declare命令將把指定的變量定義為整數(shù)型變量,賦予整數(shù)型變量的任何類型的值都將被轉換成整數(shù),下面通過實例來了解一下整數(shù)型變量的賦值。使用-x選項,declare命令將把指定的變量通過環(huán)境輸出到后續(xù)命令。使用-p選項,declare命令將顯示指定變量的屬性和值。5.4.5Bash中的數(shù)組變量一個數(shù)組是包含多個值的變量。任何變量也可以作為一個數(shù)組使用。數(shù)組的大小沒有限制,也不需要成員變量是連續(xù)分配的。數(shù)組的索引是從0開始的,即第一個元素的索引是0。間接聲明一個數(shù)組變量的語法如下所示:$ARRAYNAME[INDEX]=valueINDEX是一個正數(shù),或是一個值為正數(shù)的算術表達式。顯式聲明一個數(shù)組變量是使用Bash的內部命令declare:$declare-aARRAYNAME帶有一個索引編號的聲明也是接受的,但索引編號將被忽略。數(shù)組的屬性可以使用Bash的內部命令declare和readonly指定,這些屬性將被應用到數(shù)組中的所有變量。5.4.5Bash中的數(shù)組變量數(shù)組變量還可以使用復合賦值的格式:$ARRAYNAME=(value1value2…valueN)若要引用數(shù)組中某一項的內容,必須要使用花括號“{}”。如果索引編號是‘@’或‘*’,那么數(shù)組的所有成員都將被引用。如果引用數(shù)組時,不指定索引編號,則引用的將是數(shù)組中的第一元素,即使用索引編號0。使用unset命令可以消除一個數(shù)組或數(shù)組的成員變量。Bash的各種參數(shù)擴展也可以應用于數(shù)組變量。5.5Shell算術運算5.5.1Bash的算術運算符Bash中的算術運算符以及它們的優(yōu)先級、結合性和值都與C語言相同。5.5.2數(shù)字常量默認情況下,Shell算術表達式都是使用十進制數(shù),除非這個數(shù)字有特定的前綴或標記。以0開頭的常量將被當作八進制數(shù)解釋,而已“0x”或“0X”開頭的數(shù)值將被解釋為十六進制數(shù)。此外,如果數(shù)值的格式是BASE#NUMBER,BASE是介于2到64之間的十進制數(shù),表示算術進制基數(shù),比如,BASE是數(shù)字12,那么12#NUMBER就表示12進制數(shù),NUMBER即為此進制中的數(shù)值。5.5.3使用算術擴展和let進行算術運算算術擴展可以對算術表達式求值并替換成所求得的值。它的格式是:$$((算術表達式))注意:算術擴展中的運算數(shù)只能是整數(shù),算術擴展不能對浮點數(shù)進行算術運算。算術表達式中的所有符號都會進行參數(shù)擴展,字符串擴展、命令替換和引用去除。算術表達式也可以是嵌套的。如果算術表達式無效,Bash將打印指示錯誤的信息,并且不會進行任何替換。5.5.3使用算術擴展和let進行算術運算let命令是Bash的內部命令,它也同樣可以用于算術表達式的求值。let命令按照從左到右的順序將提供給它的每一個參數(shù)進行算術表達式的求值。求值運算只能使用固定寬度的整數(shù),并且不會檢查溢出,但是它可以捕獲除以0的情況并報錯。當最后一個參數(shù)的求值結果為真時,let命令返回退出碼0,否則返回退出碼1。let命令的功能和算數(shù)擴展基本相同。但let語句要求默認情況下在任何操作符兩邊不能含有空格,即所有算術表達式要連接在一起。若要在算術表達式中的符號之間使用空格就必須使用雙引號將算術表達式括起。5.5.4實例:使用expr命令expr命令是一個用于對表達式進行求值并輸出相應結果的命令行工具。它同樣也只支持整數(shù)運算數(shù),不支持浮點運算數(shù)的運算。與let命令相反,使用expr命令時,表達式中的運算符左右必須包含空格,如果沒有空格,而是將運算符與運算數(shù)直接相連,expr命令將不會對表達式進行求值,而直接輸出算術表達式。使用expr命令時,對于某些運算符,還需要使用符號‘\’進行轉義,否則提示語法錯誤。使用expr命令給變量賦值時,需要使用Shell擴展中的命令替換(請參考2.4.2章節(jié))。5.6退出腳本5.6.1退出狀態(tài)碼每一個命令都會返回一個退出狀態(tài)(有時被稱作返回狀態(tài)或退出碼)。一個運行成功的命令會返回一個0。而不成功的會返回一個非0的值,它通??梢员唤忉尀橐粋€錯誤代碼。功能良好的Linux命令、程序或工具當成功完成時,會返回退出狀態(tài)碼0。同樣地,Shell腳本和它里面的函數(shù)也會返回一個退出狀態(tài)碼。在Shell腳本或函數(shù)中,最后執(zhí)行的一條命令決定其退出狀態(tài)。你可以通過檢查Bash的特殊變量$?(請參見5.4.3節(jié))來查看上一條命令運行后的退出狀態(tài)碼。在你的腳本中檢查你調用的程序的退出狀態(tài)是非常重要的。當你的腳本運行完成時,返回一個有意義的退出狀態(tài)也同樣是非常重要的。5.6.2實例:使用exit命令exit命令的語法如下所示:$exitNexit命令語句用于從shell腳本中退出并返回指定的退出狀態(tài)碼N,來指示Shell腳本是否成功結束。當錯誤發(fā)生時,使用exit命令語句可以終結腳本的運行。當N為0時,表示腳本成功運行正常退出;而當N為非0時,表示腳本運行失敗,由于錯誤而退出運行。退出狀態(tài)碼N可以被其它命令或腳本使用來采取它們自己的行為。如果退出狀態(tài)碼N被省略,則將把最后一條運行的命令的退出狀態(tài)作為腳本的退出狀態(tài)碼。5.7實例:調試腳本Shell腳本調試的主要工作是發(fā)現(xiàn)引發(fā)腳本錯誤的原因,以及在腳本中定位發(fā)生錯誤的行。Bash提供了多種腳本調試的功能。但最常用的腳本調試方法是使用Bash的-x選項啟動一個子Shell,它將以調試模式運行整個腳本,使Shell在執(zhí)行腳本的過程中把實際執(zhí)行的每一個命令行顯示出來,并且在命令行的行首顯示一個‘+’號,‘+’號后面顯示的是經過了參數(shù)擴展之后的命令行的內容,有助于分析實際執(zhí)行的是什么命令。5.7實例:調試腳本Bash的執(zhí)行選項除了可以在啟動Shell是指定外,也可以在腳本中用set命令來指定?!皊et-選項”表示啟動某選項,“set+選項”表示關閉某選項。所以我們可以在Shell腳本中使用“set-x”和“set+x”命令來調試腳本中的某一段代碼。Bash中還有一個“-v”選項,該選項將激活詳細輸出模式,在這一模式中,由Bash讀入的腳本的每一個命令行都將在執(zhí)行前被打印輸出。通常,將-v選項和-x選項同時使用,可以得到更為詳細的腳本調試信息5.7實例:調試腳本從上面的幾個實例你可能發(fā)現(xiàn),-x選項雖然使用起來比較方便,但它輸出的調試信息僅限于參數(shù)擴展之后的每一條實際執(zhí)行的命令以及行首的一個‘+’號,但卻沒有代碼行的行號這樣的重要信息,這對于調試復雜的Shell腳本來說,是很不方便的。幸運的是,Bash的一些內部環(huán)境變量可以用來增強-x選項的輸出信息,下面介紹幾個有用的Bash內部環(huán)境變量:$LINENO:表示Shell腳本的當前行號。$FUNCNAME:它是一個包含了當前在執(zhí)行調用堆棧中的所有Shell函數(shù)名稱的數(shù)組變量。${FUNCNAME[0]}代表當前正在執(zhí)行的Shell函數(shù)的名稱,${FUNCNAME[1]}則代表調用函數(shù)${FUNCNAME[0]}的函數(shù)的名字,以此類推。$PS4:我們在前面已經講到,使用Bash的-x選項時,每一條實際執(zhí)行的命令的行首會顯示一個‘+’號,而這個‘+’號其實就是變量$PS4的默認值。利用變量$PS4的這一特性,結合上述的另兩個Bash內部變量,通過重新定義變量$PS4,我們就可以增強-x選項的輸出信息。5.7實例:調試腳本由于上面實例的腳本中沒有函數(shù),所以${FUNCNAME[0]}的輸出為空。Bash中還有其它一些對調試腳本有幫助的內置變量,比如$BASH_SOURCE、$BASH_SUBSHELL等,你可以使用Bash的參考手冊(manbash)來查看,然后根據(jù)你的調試目的,使用這些變量來重新定義變量$PS4,從而達到增強Bash的-x選項的輸出信息的目的。Bash中還有一個執(zhí)行選項-n,它可用于測試Shell腳本中是否存在語法錯誤,它會讀取腳本中的命令但不會執(zhí)行它們。在編寫完Shell腳本后,實際執(zhí)行之前,最好首先使用-n選項來測試腳本中是否存在語法錯誤,這是一個好的習慣。因為某些Shell腳本在執(zhí)行時會對系統(tǒng)環(huán)境產生影響,如果在實際執(zhí)行時才發(fā)現(xiàn)語法錯誤,你可能不得不手工地做一些恢復工作才能繼續(xù)測試這個腳本。5.8Shell腳本編程風格每個代碼行不多于80個字符。保持一致的縮進深度。程序結構的縮進應與邏輯嵌套深度保持一致。在每一個代碼塊之間留一個空行,可以提高腳本的可讀性。每個腳本文件必須要有一個文件頭注釋,任何一個不簡短的且不顯而易見的函數(shù)都需要注釋,腳本中任何復雜的、不是顯而易見的、以及重要的代碼部分都需要注釋。文件頭提供文件名和它的內容等一些信息。自定義的變量名或函數(shù)名使用小寫字母,使用下劃線‘_’分隔單詞。程序和腳本的返回值需要使用變量$?進行驗證。5.9小結下面我們總結一下本章所學的主要知識:#!(Shebang)是一個由井號‘#’和嘆號‘!’構成的字符序列。它是出現(xiàn)在Shell腳
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 認知康復指導
- 新生兒護理敏感指標管理
- 養(yǎng)老社區(qū)智能化建設與社區(qū)居民需求匹配度研究報告
- 胸腔閉式引流水封瓶護理
- 牙齦癌的護理查房案例
- 無痛康復演講
- 呼吸機系統(tǒng)組成結構
- 突發(fā)性耳聾的治療及護理
- 電影中的心理疾病呈現(xiàn)與解析
- 《函數(shù)的單調性》名師課件2
- 初中英語閱讀理解專項練習26篇(含答案)
- 國家開放大學《理工英語4》綜合練習參考答案
- 鐵路安檢工作總結
- 發(fā)動機節(jié)能減排技術研究
- 腰椎間盤脫出伴坐骨神經痛的健康宣教
- 談心談話記錄2024年簡短
- 陜09J01 建筑用料及做法圖集
- 疼痛科護士對疼痛科護理質量提升的策略與方法
- 會員維護培訓課件
- 郵政網點主題營銷活動
- 2022屆高三化學一輪復習實驗強基練12無機物制備類探究實驗含解析
評論
0/150
提交評論