Linux 伺服器系統管理第十三章 Shell Script 程式設計      下一頁

第十三章 Shell Script 程式設計

內容:

  • 13-1 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 環境以供各種程式呼叫,亦即每一個命令稿都可以宣告自己的執行環境,如shcshbashperl等等。本章採用相容性最高的 bash 來介紹 Shell script 的各種語法,相信這些敘述語句在其他 Shell 應該都可以相容。

13-1-1 Shell Script 執行

先不考慮相關控制敘述,僅就簡單的命令敘述所編寫的一個批次檔案,來觀察 Shell script 的執行程序。以下是利用 vi 所編輯的程式範例$vi ex7_1

# A simple shell script

# file name:ex7_1

cal

date

who

上述 Script 中,井號(#)後面的任何文字都是『註解』,作為程式說明使用,並不是程式內容,接下來是連續三個 Shell 命令 caldate who。編輯完後,利用 ls –l 命令觀察它的屬性如何,操作如下:

$ ls -l ex7_1

-rw-rw-r--  1 tsnien tsnien 61 Jul 21 09:50 ex7_1

我們可以發現,編輯後的 ex7_1 僅是一般文書檔案,而且使用者沒有執行該程式的權利,但可以利用下述兩種方法執行該程式(其餘 Shell script 也是如此):

A. 執行 Shell script

呼叫某一個 Shell 來執行該 Shell script,譬如,shBourne shell)、bashBash shell)或 cshC Shell),以bash為例如下:$bash shell.scr

$ bash ex7_1                             【執行 bash 程式】

     July 2005                           【執行 cal 命令結果】

Su Mo Tu We Th Fr Sa

             1  2

3  4 5  6  7  8  9

10 11 12 13 14 15 16

17 18 19 20 21 22 23

24 25 26 27 28 29 30

31

Thu Jul 21 10:00:10 CST 2005               【執行 date 命令結果】

root     :0           Jul 20 08:54        【執行 who 命令結果】

tsnien   pts/9        Jul 21 09:35 (140.127.138.31)

B. 變更執行權利】

另一種方法是將 Shell script 設定成可執行檔,並且讓使用者可以直接執行,設定方法如下$ chmod u+x ex7_1

$ chmod u+x ex7_1r

$ ls -l shell.scr

-rwxrw-r--  1 tsnien tsnien 61 Jul 21 09:50 ex7_1

既然 ex7_1 已成為可執行檔(對 User 本身而言),執行方法如下:$ ./ex7_1

$ ./ex7_1

     July 2005

Su Mo Tu We Th Fr Sa

               1  2

3  4  5  6  7  8  9

10 11 12 13 14 15 16

17 18 19 20 21 22 23

24 25 26 27 28 29 30

31

Thu Jul 21 10:23:06 CST 2005

root     :0           Jul 20 08:54

tsnien   pts/9        Jul 21 09:35 (140.127.138.31)

上述命令是因為 PATH 變數沒有指定到『目前目錄』(Current directory.),而必須採用相對路徑來表示命令的所在位置。我們藉由設定 PATH 變數,讓它可以到目前目錄下搜尋命令,設定方法如下:(請編寫到 .bash_profile 檔案內)

$ PATH=$PATH:.        PATH 變數內增加 “:.” 為目前目錄】

$ export PATH

$ echo $PATH

/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin: /home/tsnien/bin:.

C. shell 執行】

上述範例是將命令稿設定成可執行檔,並直接執行該命令稿,如果沒有指定在哪一個 Shell 執行該命令稿,就表示在目前 Shell 下執行該命令稿。其實,我們可以在命令稿內指定(或呼叫)一個『子 shell』(Sub-shell)來執行,指定方法是加在命令稿的第一行(必須第一行才行),寫下指定的 Sub-shell 名稱,格式為 #! Sub-shell。範例如下:$vi ex7_1

#! /bin/bash

# A simple shell script

# file name:shell.scr

cal

date

who

讀者可以試試其他的 Shell(如 /bin/sh/bin/csh),可發現執行的結果都會相同,但對其他的命令稿就不盡然。

13-1-2 Shell script 變數

之前第六章介紹過,Shell 環境有環境變數、自訂變數與位置變數等三種類型的變數,Shell script 也都可以直接存取它們,其中又以環境變數與 Shell 環境設定最有關係,因已在第六章介紹過,這裡不再重複。然而對程式設計而言,位置變數與自訂變數則較有關聯,以下分別介紹這兩種變數的特性。

A. 使用者自訂變數】

任何程式語言都需要宣告變數,程式運作也是針對變數做一些處理,並得到最後的結果。Shell script 也不例外,可依照使用者的需求產生各種變數,來輔助程式的執行,此類型變數大多使用完即拋棄,而與系統環境無關,通常稱為『自訂變數』。一般 Shell(如 csh sh)的自訂變數大多無法指定變數型態,也不需要事先宣告直接採用即可。我們用一個簡單的範例,來說明自訂變數的產生與使用方法,程式如下:$vi ex7_2

#! /bin/bash

# User defind variables

int=5

float=5.5

char=character

string="Good luck to you"

echo "integer = $int"

echo "float = $float"

echo "char = $char"

echo "string = $string"

其中 int=5(注意,等號前後不可以空格),表示產生一個名稱為 int 的變數,並且直接將 5 填入該變數內。另外,變數 floatchat string 都是以相同的方法產生。其實填入變數的內容是不分整數、浮點數、字元或字串,而是將所欲填入的內容以 ASCII 碼方式填入,至於該變數為何種型態,待爾後使用時再去判斷處理。當變數做某些處理時,必須在變數的前面增加一個錢號($),代表變數而非字串。然而所謂的「處理」可能是輸出(echo)、運算(expr)、條件判斷(test)等等(容後介紹)。上述範例執行結果如下:

$ ex7_2                 【執行 ex7_2 程式】

integer = 5

float = 5.5

char = character

string = Good luck to you

$ echo $string                   【觀察 string 變數內容】

 

$ echo $char                    【觀察 char 變數內容】

 

最後兩道的命令,表示執行完 variable1 程式後,觀察是否有自訂變數遺留下來,其中 string char variable1 程式內的自訂變數,測試後發現這兩個變數都不存在。也就是說,當系統產生一個 process(行程,第 12 章介紹)來執行 Shell script 程式時,執行完後該 process 便不存在,它所產生的自訂變數也不會遺留下來。

B. 位置變數】

位置變數(Positional variable)非常類似 C 語言的 argv args 變數。簡單的說,位置變數是命令行所輸入的字元變數,以 $0(如 C 語言的 argv[0])表示命令本身、$1 為第一個攜帶參數、$2 為第二個參數,依此類推。而且以 $* 表示所有參數($1 以後的字元變數),$#(如 C 語言的 args)表示所攜帶參數的個數。範例如下:

命令行為:$ cp /etc/passwd file_1

相關位置變數:

$0 = cp

$1 = /etc/passwd

$2 = file_1

$* = /etc/passwd file_1

$# = 2

由上述可以看出,位置變數就是一般程式語言所說的『位置參數』(Position parameter),也就是執行某一程式時,給予相當的參數,而這些參數放置於命令行內,再利用它放置的次序來分辨。接下來,我們用一個簡單的外殼程式來介紹位置變數的使用方法,外殼程式如下:ex7_3,利用 vi 編輯)

#! /bin/sh

# Illustrate the use of position parameter

 

echo "first parameter = $1"

echo "second parameter = $2"

echo "third parameter = $3"

echo "your typed $# argnment: $*"

執行結果如下:

$ chmod u+x ex7_3

$ ./ex7_3 Good Luck To You             【執行 ex7_3 程式】

first parameter = Good

second parameter = Luck

third parameter = To

your typed 4 argument: Good Luck To You

由上述範例可以看出,$1 為第一個位置參數(Good),$2 為第二個位置參數(Luck);另外,$# 為參數的數目(4),$* 為所有參數。

 

翻轉工作室:粘添壽

 

Linux 伺服器系統管理 - CentOS:

 

 

 

翻轉電子書系列: