2007年5月26日 星期六

基本 bash 程式設計 (1) - Script & Function

Shell Script 簡介

其實 shell script 說穿了,就是一群指令的集合而已,不過藉由程式設計師的創意,可以寫出功能強大的 shell script 來完成許多複雜的工作,對一個想要讓管理工作更有效率(其實是想偷懶)的管理者來說,實在是不能不學的一門課程。

一些廢話就不說了,應該大家都知道 Linux 的檔案權限吧,shell script 沒有執行(x)權限是沒辦法使用的喔!

再來說明 Shell Script 執行的方式,假設我們有一支 shell script 稱為 alice,裡面有兩行指令,分別是 hatter 以及 gryphon,在 Linux 中,一共有三種方法可以來執行這支 shell script,分別是:
(a) source alice
(b) ./alice
(c) source alice &
這三種方式,都可以順利的執行 alice 這一支 script,但是.......有何差別呢? 答案是....「script 是否進入 subshell 中執行

以下用一張圖來說明三種執行方式的差異:

看出來了嗎? 在 (a) 與 (b) 中,使用者都必須等待程式執行完畢,才能接手繼續工作,而兩者的差異在於 script 是否進入了 subshell 中執行;或許一般人覺得這兩種方式似乎沒有差異,但試想,如果管理者在 subshell 修改了許多 shell 的環境設定,此時 script 進入 subshell 中執行就變的很不一樣了! (例如:有不同的 PATH 設定、其他各種 alias command....等等 )

而第三種呢? 除了 script 進入 subshell 中執行外,而且還是在背景處理,完全不會干擾到管理者目前的工作,此種執行方式在於 script 需要跑相當長一段時間的情況下就相當好用了,管理者可以斟酌使用。


Function (函式) 的使用

現在任何高階的程式語言都講求物件導向了,shell script 當然不能連最基本的 function 功能都不支援囉! 而使用 function 的好處有兩個:
  1. 功能模組化
    這不需要費心解釋吧? 這不就是 function 的主要目的嗎?
  2. 加快速度
    shell script 的 function 就像 Java 中 class 的 static method 一樣,系統會預先配置記憶體位置給他,因此可以直接使用且速度較快! 一般來說,目前電腦的記憶體都相當的大,因此在一般情況下(embedded system 中例外啦....)不需要為了省一點記憶體空間都不用 function,利用 function 可以大大降低工作的複雜度。

而 function 定義的方式有兩種,分別是:
function 函式名稱 {
......

......

}
或是
函式名稱() {
......

......

}
====== 以下為備註 ======
第一種方式在「Ubuntu中直接執行 shell script 會產生錯誤喔! 原因是系統會將「function 函式名稱」視為指令來執行....所以就錯了.....(在 RedHat 系列的 Linux 就很正常!)

不過有個很簡單的方法可以處理,只要在執行之前先 source 該 script 即可

而上述兩種撰寫方式所執行出來的並無不同,管理者儘管選擇自己喜歡的去寫即可。

而在每個使用者登入 Linux 系統時,其實就已經存在很多已經預先定義好的 function,可以打下列指令列出預先定義的 function 及其內容:
shell> declare -f
而 function 跟 script 有何不同呢? 以下分兩點說明:
  1. function 不會執行於 subshell,因此與 script 是在同一個 process 中完成
  2. 當 script 名稱與 function 名稱相同時,執行時會以執行 function 為優先

另外附帶,關於執行順序,優先順序如下:
  1. Alias
  2. 系統中的關鍵字
  3. 函式
  4. 系統中內建的工具
  5. script 或其他執行程式

若有遇到同名的問題,管理者必須瞭解執行的優先順序為何,才有辦法順利的 debug。

基本上,不論是 alias、keyword、function、或是其他程式,都有一個名稱(name),而同樣的名稱,又有可能是 alias、keyword、function.....的名稱,那應該要如何判斷某個名稱(name)的型態為何呢? Linux 中提供了一個好用的工具指令「type」,以下擷取 type 的 manpage 內容:
type [-aftpP] name [name ...]
With no options, indicate how each name would be interpreted if
used as a command name. If the -t option is used, type prints a
string which is one of alias, keyword, function, builtin, or
file if name is an alias, shell reserved word, function,
builtin, or disk file, respectively. If the name is not found,
then nothing is printed, and an exit status of false is
以下舉幾個使用 type 的例子:
# 顯示「file」
shell> type -t bash

# 顯示「keyword」
shell> type -t if
或許平常 type 使用到的機會可能不多,不過或許有天會成為 debug 的利器也說不定喔!


參考資料:
  1. Introduction To Bash Shell Scripting
  2. Learning The Bash Shell, 3/e

沒有留言:

張貼留言