Linux 伺服器系統管理:第十三章 Shell Script 程式設計 下一頁 |
第十三章 Shell Script 程式設計
13-1 Shell Script 程式簡介 『命令稿』(Script)與批次(Batch)檔案非常類似,都是集合多個命令(或稱公用程式)而成為另一個命令,然而命令稿的功能比批次檔案強了許多。一般『命令行』(Command line)每次僅能輸入一行命令,利用 Enter 鍵表示結束並傳送給系統執行。雖然『命令行』也利用其他方法(譬如管道,|),將多個命令整合且一併傳送給系統執行,但沒有將它編制成檔案,這是『批次』與『命令稿』之間的差別。批次檔案僅將多個命令編寫成一個檔案,要求系統依照檔案內『順序』執行命令,命令稿則不然。命令稿可以在命令檔案內中加入一些控制程序,如判斷敘述(if/else)、迴圈敘述(for/while/until)等等,並非僅順序執行,而是會依照狀況改變執行程序。所以命令稿是屬於程式化的敘述 Shell 命令,因此稱之為『Shell script』(外殼命令稿)。從 Shell 的最基礎架構開始,Shell 命令就是為了整合許多系統函數編寫而成,利用它可以輕易的操作系統,是最基本的使用者介面。然而,當基本工具不能滿足使用者所需時,就得利用 Shell script 整合多個 Shell 命令,並於其中加入適當的敘述語句,如此便可製作出更符合使用者所需的工具。簡單的說,Shell script 最主要的功能就是整合多個 Shell 命令,並建立出新的 Shell 命令。 命令稿是一種直譯程式,可以直接執行;而一般程式語言(如 C 語言)都必須經過編譯程式,將原始程式翻譯成目的碼(Object file),再連結多個目的碼成為一個可執行檔。然而,一般命令稿大多不需要經過編譯成目的碼,也沒有連結多個程式的功能,命令稿的語句都可以直接執行,無需經過編譯。 除了建立新命令之外,我們也可以發現大部分 Unix/Linux 系統的運作程序,都是利用 Shell Script 所描述而成。由此可見,想要了解或管理 Unix/Linux 系統,認識 Shell script 是不容或缺的,這也是本章介紹 Shell script 最主要的目的。從另一個角度來看,目前在 Unix/Linux 系統上雖有許多不同的 Shell,但在 Unix/Linux 系統上,除了 Shell 之間大致上可以相容之外,還可以在每一個 Shell script 程式指定自己所屬的 Shell 環境,通常系統也都會安裝多個 Shell 環境以供各種程式呼叫,亦即每一個命令稿都可以宣告自己的執行環境,如sh、csh、bash、perl等等。本章採用相容性最高的 bash 來介紹 Shell script 的各種語法,相信這些敘述語句在其他 Shell 應該都可以相容。 13-1-1 Shell Script 執行 先不考慮相關控制敘述,僅就簡單的命令敘述所編寫的一個批次檔案,來觀察 Shell script 的執行程序。以下是利用 vi 所編輯的程式範例($vi ex7_1):
上述 Script 中,井號(#)後面的任何文字都是『註解』,作為程式說明使用,並不是程式內容,接下來是連續三個 Shell 命令 cal、date 與 who。編輯完後,利用 ls –l 命令觀察它的屬性如何,操作如下:
我們可以發現,編輯後的 ex7_1 僅是一般文書檔案,而且使用者沒有執行該程式的權利,但可以利用下述兩種方法執行該程式(其餘 Shell script 也是如此): 【A. 執行 Shell script】 呼叫某一個 Shell 來執行該 Shell script,譬如,sh(Bourne shell)、bash(Bash shell)或 csh(C Shell),以bash為例如下:($bash shell.scr)
【B. 變更執行權利】 另一種方法是將 Shell script 設定成可執行檔,並且讓使用者可以直接執行,設定方法如下($ chmod u+x ex7_1):
既然 ex7_1 已成為可執行檔(對 User 本身而言),執行方法如下:($ ./ex7_1)
上述命令是因為 PATH 變數沒有指定到『目前目錄』(Current directory,.),而必須採用相對路徑來表示命令的所在位置。我們藉由設定 PATH 變數,讓它可以到目前目錄下搜尋命令,設定方法如下:(請編寫到 .bash_profile 檔案內)
【C. 子 shell 執行】 上述範例是將命令稿設定成可執行檔,並直接執行該命令稿,如果沒有指定在哪一個 Shell 執行該命令稿,就表示在目前 Shell 下執行該命令稿。其實,我們可以在命令稿內指定(或呼叫)一個『子 shell』(Sub-shell)來執行,指定方法是加在命令稿的第一行(必須第一行才行),寫下指定的 Sub-shell 名稱,格式為 #! Sub-shell。範例如下:($vi ex7_1)
讀者可以試試其他的 Shell(如 /bin/sh、/bin/csh),可發現執行的結果都會相同,但對其他的命令稿就不盡然。 13-1-2 Shell script 變數 之前第六章介紹過,Shell 環境有環境變數、自訂變數與位置變數等三種類型的變數,Shell script 也都可以直接存取它們,其中又以環境變數與 Shell 環境設定最有關係,因已在第六章介紹過,這裡不再重複。然而對程式設計而言,位置變數與自訂變數則較有關聯,以下分別介紹這兩種變數的特性。 【A. 使用者自訂變數】 任何程式語言都需要宣告變數,程式運作也是針對變數做一些處理,並得到最後的結果。Shell script 也不例外,可依照使用者的需求產生各種變數,來輔助程式的執行,此類型變數大多使用完即拋棄,而與系統環境無關,通常稱為『自訂變數』。一般 Shell(如 csh 或 sh)的自訂變數大多無法指定變數型態,也不需要事先宣告直接採用即可。我們用一個簡單的範例,來說明自訂變數的產生與使用方法,程式如下:($vi ex7_2)
其中 int=5(注意,等號前後不可以空格),表示產生一個名稱為 int 的變數,並且直接將 5 填入該變數內。另外,變數 float、chat 與 string 都是以相同的方法產生。其實填入變數的內容是不分整數、浮點數、字元或字串,而是將所欲填入的內容以 ASCII 碼方式填入,至於該變數為何種型態,待爾後使用時再去判斷處理。當變數做某些處理時,必須在變數的前面增加一個錢號($),代表變數而非字串。然而所謂的「處理」可能是輸出(echo)、運算(expr)、條件判斷(test)等等(容後介紹)。上述範例執行結果如下:
最後兩道的命令,表示執行完 variable1 程式後,觀察是否有自訂變數遺留下來,其中 string 與 char 為 variable1 程式內的自訂變數,測試後發現這兩個變數都不存在。也就是說,當系統產生一個 process(行程,第 12 章介紹)來執行 Shell script 程式時,執行完後該 process 便不存在,它所產生的自訂變數也不會遺留下來。 【B. 位置變數】 位置變數(Positional variable)非常類似 C 語言的 argv 與 args 變數。簡單的說,位置變數是命令行所輸入的字元變數,以 $0(如 C 語言的 argv[0])表示命令本身、$1 為第一個攜帶參數、$2 為第二個參數,依此類推。而且以 $* 表示所有參數($1 以後的字元變數),$#(如 C 語言的 args)表示所攜帶參數的個數。範例如下:
由上述可以看出,位置變數就是一般程式語言所說的『位置參數』(Position parameter),也就是執行某一程式時,給予相當的參數,而這些參數放置於命令行內,再利用它放置的次序來分辨。接下來,我們用一個簡單的外殼程式來介紹位置變數的使用方法,外殼程式如下:(ex7_3,利用 vi 編輯)
執行結果如下:
由上述範例可以看出,$1 為第一個位置參數(Good),$2 為第二個位置參數(Luck);另外,$# 為參數的數目(4),$* 為所有參數。
|
翻轉工作室:粘添壽
Linux 伺服器系統管理 - CentOS:
翻轉電子書系列:
|