溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Shell 編程從入門到精通 - 第 03 章

發(fā)布時(shí)間:2020-08-07 07:23:22 來源:ITPUB博客 閱讀:167 作者:Bao塔鎮(zhèn)河妖 欄目:建站服務(wù)器

Shell 編程的基本元素


    編程語言變量類型:變量對于編程語言來說很重要,編程語言使用變量來存儲(chǔ)數(shù)據(jù),執(zhí)行運(yùn)輸。
     靜態(tài)類型語言:一種在編譯期間就確定數(shù)據(jù)類型的語言。大多數(shù)是通過在使用任一變量之前聲明其數(shù)據(jù)類型來保證這一點(diǎn),例如 JAVA 和 C。
     動(dòng)態(tài)類型語言:一種在運(yùn)行期間才去確定數(shù)據(jù)類型的語言。它確定一個(gè)變量的類型是在第一次給變量賦值的時(shí)候,例如 VBScript 和 Pthyhon。
     強(qiáng)類型語言:一種總是強(qiáng)制類型定義的語言,當(dāng)有一個(gè)整數(shù)時(shí),不進(jìn)行明確轉(zhuǎn)換,不能把它當(dāng)做一個(gè)字符串,例如 JAVA 和 Python。
     弱類型語言:一種類型可以被忽略的語言,整數(shù)變量可以看做字符串,例如 VBScript 和 Shell。

Shell 編程從入門到精通 - 第 03 章

Shell 編程從入門到精通 - 第 03 章

Shell 編程從入門到精通 - 第 03 章

     從上圖的例子中可以看出,Bash Shell 中的變量是不區(qū)分類型的。
     shell 中的三種變量,用戶變量在編程過程中使用最多,位置變量在對參數(shù)判斷和命令返回值判斷時(shí)會(huì)使用,環(huán)境變量主要是在程序運(yùn)行的時(shí)候需要設(shè)置。
     用戶變量:用戶在 shell 編程過程中定義的變量,分為局部變量和全局變量。默認(rèn)情況下,用戶定義的變量都是全局變量,使用 local 限定詞定義的才是局部變量。變量定義的語法為 varname=value。等號兩邊不能有空格,而且變量值多余一個(gè)單詞的情況下,需要將值用引號括起來。在命令中引用變量值時(shí),需要在變量名前加上 $。
     unset varname 可以刪除變量,但 shell 在遇到未定義變量時(shí)返回錯(cuò)誤,因此在正常情況下并不這樣使用。
    
     大括號操作符可以使用 shell 字符串操作的更多高級功能,即字符串處理運(yùn)算符。它可以完成:確保變量存在且有值;設(shè)置變量的默認(rèn)值;捕獲未設(shè)置變量而導(dǎo)致的錯(cuò)誤;刪除匹配模式的變量的值部分內(nèi)容。

Shell 編程從入門到精通 - 第 03 章
    
     上表中每個(gè)冒號都是可選的,如果省略冒號,則將每個(gè)定義中的“存在且非 null”改為“存在”,即變量運(yùn)算符只判定變量是否存在。

Shell 編程從入門到精通 - 第 03 章
Shell 編程從入門到精通 - 第 03 章

     模式匹配運(yùn)算符可以對值進(jìn)行操作,通常用于切割路徑名稱或文件名后綴

Shell 編程從入門到精通 - 第 03 章

     上圖中的變量替換,使用了兩種方法,將 PATH 變量中的冒號都替換成了換行符。

Shell 編程從入門到精通 - 第 03 章

     再舉一個(gè)例子,通過模式匹配刪除等號(包括等號)之后的所有字符,輸出部分就是變量名,刪除等號(包括等號)之前的所有字符,輸出部分就為變量值。

Shell 編程從入門到精通 - 第 03 章

     ${#varname}參數(shù)返回 varname 值字符串中的字符個(gè)數(shù)。
     除了通過賦值語句與通過用戶將變量作為命令行參數(shù)給出獲取變量值之外,另外一種方法為命令替換。它允許使用命令的標(biāo)準(zhǔn)輸出,就像一個(gè)變量值一樣,語法為 `command`,這里 ` 為反引號,它將命令的輸出作為表達(dá)式值。
    位置變量:也稱為系統(tǒng)變量、位置參數(shù),是 shell 腳本運(yùn)行時(shí)傳遞給腳本的參數(shù),同時(shí)也表示在 shll 函數(shù)內(nèi)部的函數(shù)參數(shù)。它們的名字是以數(shù)字命名 $0~$9,如果超過這個(gè)范圍需要用括號括起來,即 ${10}。
    
Shell 編程從入門到精通 - 第 03 章

Shell 編程從入門到精通 - 第 03 章

     上圖中是幾個(gè)常見的位置變量。其中 $# 輸出變量的個(gè)數(shù);$? 輸出上條命令的返回值;$0 輸出命令的名字;$* 輸出所有參數(shù),在雙引號中使用 \ 進(jìn)行轉(zhuǎn)義。

Shell 編程從入門到精通 - 第 03 章

Shell 編程從入門到精通 - 第 03 章

     上圖程序運(yùn)行過程解釋如下:判斷運(yùn)行參數(shù)個(gè)數(shù),如果不等于 2,顯示 Usage 內(nèi)容,$0 代表的是腳本自身;用 grep 命令在 $2 文件中查找 $1 字符串;判斷前一條命令的返回值,成功顯示找到的相關(guān)信息,不成功則顯示 echo 內(nèi)容;在雙引號中要顯示引號,需要加上 \ 轉(zhuǎn)義。
     shell 中內(nèi)置了一個(gè) shift 命令,它可以“截去”參數(shù)列表中最左端的一個(gè),執(zhí)行了 shift 后,$1 的值將會(huì)丟失,而 $2 的值將會(huì)賦給 $1,以此類推。$# 輸出結(jié)果也會(huì)減一。shift 命令默認(rèn)為 shift 1,即截去一個(gè)參數(shù)。

Shell 編程從入門到精通 - 第 03 章

Shell 編程從入門到精通 - 第 03 章

     上例演示了 shift 的作用,將文件名作為參數(shù)傳入腳本中,每次讀取一個(gè)文件。另外也使用了循環(huán)的方式來實(shí)現(xiàn)此功能。
     環(huán)境變量:影響當(dāng)前 shell 進(jìn)程運(yùn)行情況的變量。
     shell 執(zhí)行命令的順序:交互 shell 在獲得用戶輸入時(shí),并不是直接在 PATH 路徑中查找,而是按照固定順序依次查找命令位置。搜索順序?yàn)閯e名(alias)、關(guān)鍵字(if、for)、函數(shù)、內(nèi)置命令(cd、pwd)、外部命令(腳本或可執(zhí)行程序,到這里才在 PATH 路徑中查找)。
     使用函數(shù)需要遵循以下的規(guī)則:先定義,后使用;允許以給位置參數(shù)賦值的方式向函數(shù)傳遞參數(shù),函數(shù)體內(nèi)部可以使用 local 限定詞創(chuàng)建局部變量;在函數(shù)中使用 exit 命令將退出腳本,使用 return 命令退回到原本調(diào)用函數(shù)的地方,且 return 命令返回最后一條命令的退出狀態(tài);內(nèi)置命令 export -f 可以將函數(shù)導(dǎo)出到子 shell 中;可以使用 source 或 dot 命令將保存在其他文件中的函數(shù)裝入當(dāng)前腳本;函數(shù)可以進(jìn)行無限制的遞歸調(diào)用;可以使用 declare -f(-F) 找到登錄會(huì)話中定義的函數(shù)。

Shell 編程從入門到精通 - 第 03 章

     函數(shù)定義分為上圖中的兩種形式,二者沒有本質(zhì)上的區(qū)別。unset -f funcname 可以刪除定義的函數(shù),-f 提示 unset 命令刪除的是函數(shù)。

Shell 編程從入門到精通 - 第 03 章

Shell 編程從入門到精通 - 第 03 章

     首先,通過 source 命令將函數(shù)從文件中讀入,可以如使用命令一樣調(diào)用函數(shù),然后將用戶名作為參數(shù)傳入函數(shù)中,判斷用戶是否在線。

Shell 編程從入門到精通 - 第 03 章

Shell 編程從入門到精通 - 第 03 章

     參數(shù) $1 和 $2 分別對應(yīng)于函數(shù)的兩個(gè)位置參數(shù),在函數(shù)內(nèi)部獲取位置參數(shù)才將它們相加;return 命令返回兩個(gè)位置參數(shù)的和;source 命令讀入函數(shù);$? 返回上一條命令的返回結(jié)果。
     if/else 語句是 shell 內(nèi)置的最簡單的流程控制語句,用于判斷當(dāng)某條件成立時(shí),則執(zhí)行某些命令,常用于選項(xiàng)不多的情況。

Shell 編程從入門到精通 - 第 03 章

     在最簡形式(沒有 elif 和 else)中,只有當(dāng) condition 為真時(shí),才執(zhí)行 statements 語句;elif 可以有任意多個(gè),它可以選擇更多的條件,提供更多的選擇,else 語句則當(dāng)所有的 if 和 elif 的 condition 都為假時(shí)才執(zhí)行。
     命令(函數(shù))的退出狀態(tài):每一條命令或函數(shù),在退出時(shí)都會(huì)返回一個(gè)小的整數(shù)值給調(diào)用它的程序。

Shell 編程從入門到精通 - 第 03 章

     在 shell 的判斷語句中,條件(condition)實(shí)際上是語句列表而不是一般的布爾表達(dá)式。通常退出狀態(tài) 0 表示函數(shù)或命令執(zhí)行成功,非 0 數(shù)表示失敗。
     shell 語法允許在邏輯上操作退出狀態(tài),常見的有 NOT,AND 和 OR。

Shell 編程從入門到精通 - 第 03 章

     NOT 操作符是 !,在 condition 條件判斷后,用 ! 取反,再測試選擇執(zhí)行語句。AND 操作符是 &&,先判斷 condition1,成功之后再判斷 condition2,如果兩個(gè)都判斷成功,則整個(gè)判斷語句成功。OR 操作符是 ||,只要兩個(gè)或多個(gè)條件中有一個(gè)成功,則整個(gè)判斷語句成功。AND 和 OR 都是短路運(yùn)算符,即只要判斷出整個(gè)語句的真假,則直接返回,不向后繼續(xù)判斷,即使后面的語句根本無法執(zhí)行。

Shell 編程從入門到精通 - 第 03 章

     if 語句唯一可以測試的內(nèi)容是退出狀態(tài),不能用于檢測表達(dá)式的值。但是通過 test 命令或 [...]的語法檢測,此時(shí)“[”后面和“]”前面必須有空格。
     
Shell 編程從入門到精通 - 第 03 章

     shell 支持字符串的比較,結(jié)合 test 或[ ... ]命令能判斷判斷比較結(jié)果,然后再進(jìn)行相關(guān)操作。

Shell 編程從入門到精通 - 第 03 章

     將第一個(gè)位置參數(shù)傳遞給 test.sh,當(dāng) $1 不存在時(shí),顯示一條出錯(cuò)信息,如果 $1 存在且大于 0,則無顯示。-s 參數(shù)與文件名之間必須要有一個(gè)空格。$1 兩邊的引號確保即使它為一個(gè)空字符串,程序要能正常運(yùn)行。

Shell 編程從入門到精通 - 第 03 章

     如果給出的位置參數(shù)小于 2 或 $1 指定的文件不存在,則退出。
    
Shell 編程從入門到精通 - 第 03 章
Shell 編程從入門到精通 - 第 03 章

     上表為常用的關(guān)于 test 的參數(shù)。

Shell 編程從入門到精通 - 第 03 章

     首先,判斷文件是否為目錄;如果不是目錄,則判斷文件是否存在;如果文件存在,則判斷文件是否具有讀寫執(zhí)行的權(quán)限,通過則顯示 echo 語句;以上所有判定都不通過時(shí),顯示 echo 語句。
     可以使用邏輯操作符連接帶參數(shù)的判斷語句,也可以使用邏輯操作符將表達(dá)式和 shell 命令組合在一起。
     case 也是一個(gè)流程控制結(jié)構(gòu),shell 中的 case 語句可以依據(jù)可包含通配符的模式測試字符串。通常可以使用 if-elif 語句配合 test 實(shí)現(xiàn)同樣的功能,但是當(dāng)選擇數(shù)目過多時(shí),就會(huì)體現(xiàn)出語句太長的局限性。
     
Shell 編程從入門到精通 - 第 03 章

     從語法中可以看出,任何 pattern 之間都可以由 | 分割的幾個(gè)模式組成,這種情況下 expression 匹配其中任意一個(gè)模式則執(zhí)行相應(yīng)語句。模式匹配按順序依次執(zhí)行,知道匹配上為止,如果無法匹配,則不執(zhí)行任何操作。
     case 語句與 fi 語句一樣,結(jié)束時(shí)是通過字符串顛倒(reverse)。

Shell 編程從入門到精通 - 第 03 章

     判斷文件后綴,根據(jù)不同后綴選擇不同的讀取方式,最后一個(gè) * 匹配所有其他匹配不上的形式,相當(dāng)于 C 語言中的 default。
     循環(huán)可以控制某些代碼的重復(fù)行為或允許對多個(gè)對象操作。
     for 循環(huán)用于遍歷整個(gè)對象/數(shù)字列表,依次執(zhí)行每個(gè)獨(dú)立對象/數(shù)字的循環(huán)內(nèi)容,在 shell 腳本里,對象可以是命令行參數(shù)、文件名或者任何可以以列表格式建立的東西。

Shell 編程從入門到精通 - 第 03 章

     list 為名稱列表,在 for 循環(huán)中對名稱列表中的每個(gè)對象進(jìn)行相應(yīng)操作,可以通過命令/模式匹配等操作來獲取名稱列表。
    
Shell 編程從入門到精通 - 第 03 章

     兩個(gè)例子都可以遍歷 mp3 文件并且依次播放。但是使用 find 命令會(huì)層層深入文件夾依次查找,而直接列出只會(huì)包含當(dāng)前目錄的文件夾。執(zhí)行反單引號(``)之前的命令,引用結(jié)果作為字符串。for 循環(huán)中如果 in list 參數(shù)被省略,則默認(rèn)為 in "$@",即命令行參數(shù)的引用列表。
     
Shell 編程從入門到精通 - 第 03 章

     shell 中的 while 和 until 循環(huán)與傳統(tǒng)語言中的 while 和 do/until 相似,它們允許代碼在某些條件為真(或直到為真)時(shí)重復(fù)運(yùn)行。while 與 until 唯一的區(qū)別在于如何判斷 condition 的退出狀態(tài)。在 while 語句中當(dāng) condition 的退出狀態(tài)為真時(shí)循環(huán)繼續(xù)運(yùn)行,否則退出循環(huán);而 until 語句中當(dāng) condition 的退出狀態(tài)為真時(shí)循環(huán)退出,否則繼續(xù)運(yùn)行。它們中的 condition,可以是簡單的命令/列表,或者是包含 && 或 || 連接的命令,與 if 語句中的 test 一樣。

Shell 編程從入門到精通 - 第 03 章

     遍歷 PATH 路徑:先賦值 path;判斷當(dāng) path 不為空,則使用 ls -ld 列出 path 中的第一個(gè)目錄;然后截去 path 中的第一個(gè)目錄和冒號;當(dāng) path 被截成空字符串("")時(shí),退出循環(huán)。

Shell 編程從入門到精通 - 第 03 章

Shell 編程從入門到精通 - 第 03 章

     在 shell 中經(jīng)常使用 while true 或者 until false 來構(gòu)建無限循環(huán)。continue 語句用于在循環(huán)體中提早開始下一輪循環(huán),break 語句用于跳出整個(gè)循環(huán),而 continue 與break 語句也彌補(bǔ)了 shell 中沒有 goto 的不足。在多層循環(huán)中,continue n 表示會(huì)把 n 層的剩余代碼都去掉,break n 表示退出 n 層循環(huán)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI