shell程式設計(轉)
Shell程式設計(轉)[@more@]在DOS 中,你可能會從事一些例行的重覆性工作,此時你會將這些重覆性的命令寫成批次檔,只要執行這個批次檔就等於執行這些命令。大家會問在UNIX中是否有批次處理這個東東,答案是有的。在UNIX中不只有如DOS 的批次處理,它的功能比起DOS 更強大,相對地也較複雜,已經和一般的高階語言不相上下。在UNIX中大家都不叫做批次檔,而叫做Shell Script。 一般而言,Shell Script的地位和其它的可執行檔(或命令)是完全相同的,只不過Shell Script是以文字檔的方式儲存,而非二進位檔。而執行Shell Script時,必須有一個程式將其內容轉成一道道的命令執行,而這個程式其實就是Shell ,這也就是為什麼我們叫做 Shell Script的原因(往後我們稱為Script)。不同Shell 的Script基本上會有一些差異,所以我們不能將寫給A shell 的Script用B shell 執行。而在UNIX中大家最常使用Bourne Shell以及C Shell ,所以這堂課就介紹這兩種Script 的寫法。 將文字檔設為可執行的Shell Script 如果我們已經寫好Script,如何將其設成可執行檔呢?因為Script其實是一個可執行檔,所以必須將其存取權設定成可執行。我們可以使用下列命令更改存取權: chmod u+x filename 只有自己可以執行,其它人不能執行 chmod ug+x filename 只有自己以及同一群可以執行,其它人不能執行 chmod +x filename 所有人都可以執行 而我們如何指定使用那一個Shell 來解釋所寫的Script呢?幾種基本的指定方式如下所述: 1. 如果Script的第一個非空白字元不是"#",則它會使用Bourne Shell。 2. 如果Script的第一個非空白字元是"#"時,但不以"#!"開頭時,則它會使用C Shell。 3. 如果Script以"#!"開頭,則"#!"後面所寫的就是所使用的Shell,而且要將整個路徑名稱指出來。 這裡建議使用第三種方式指定Shell ,以確保所執行的就是所要的。Bourne Shell的路徑名稱為/bin/sh ,而C Shell 則為/bin/csh。 1. 使用Bourne Shell┌——————————┐ ┌——————————┐│echo enter filename │ │#!/bin/sh ││ . │ or │ . ││ . │ │ . ││ . │ │ . │└——————————┘ └——————————┘2. 使用C Shell┌——————————┐ ┌——————————┐│# C Shell Script │ │#!/bin/csh ││ . │ │ . ││ . │ │ . ││ . │ │ . │└——————————┘ └——————————┘3. 使用/etc/perl┌——————————┐│#! /etc/perl ││ . ││ . ││ . │└——————————┘除了在Script內指定所使用的Shell 外,你也可以在命令列中強制指定。比如你要用C Shell 執行某個Script,你可以下這個命令: csh filename 此時的Script的存取權就不一定要為可執行檔,其內部所指定的Shell 也會無效,詳細的情形後面會討論。 □Script的基本結構及觀念 Script是以行為單位,我們所寫的Script會被分解成一行一行來執行。而每一行可以是命令、註解、或是流程控制指令等。如果某一行尚未完成,可以在行末加上"" ,這個時候下一行的內容就會接到這一行的後面,成為同一行,如下 ┌———————————┐│echo The message is ││too long so we have ││to split it into ││several lines │└———————————┘當Script中出現"#" 時,再它後面的同一行文字即為註解,Shell 不會對其翻譯。 在Script中要執行一個命令的方法和在命令列中一樣,你可以前景或背景執行,執行命令時也會需要設定一些環境變數。 Script的流程控制和一般高階語言的流程控制沒有什麼兩樣,也和高階語言一樣有副程式。這些使得Script的功能更加強大。 為了達到與高階語言相同的效果,我們也可以在Script中設定變數,如此使Script 成為一個名付其實的高階語言。 □Bourne Shell 一、變數 Bourne Shell的變數型態只有字串變數,所以要使用數值運算則必須靠外部命令達 成目的。而其變數種類有下列幾種: 1. 使用者變數 這是最常使用的變數,我們可以任何不包含空白字元的字串來當做變數名稱。 設定變數值時則用下列方式: var=string 取用變數時則在變數名稱前加上一"$" 號。 ┌———————┐│name=Tom ││echo name ││echo $name │└———————┘結果如下:nameTom2. 系統變數(環境變數) 和使用者變數相似,只不過此種變數會將其值傳給其所執行的命令。要將一使 用者變數設定為系統變數,只要加上: export var ┌———————┐│name=Tom ││export name │└———————┘以下是使用者一進入系統之後就已設定好的系統變數: $HOME 使用者自己的目錄 $PATH 執行命令時所搜尋的目錄 $TZ 時區 $MAILCHECK 每隔多少秒檢查是否有新的信件 $PS1 在命令列時的提示號 $PS2 當命令尚未打完時,Shell 要求再輸入時的提示號 $MANPATH man 指令的搜尋路徑 3. 唯讀的使用者變數 和使用者變數相似,只不過這些變數不能被改變。要將使用者變數設成唯讀的 ,只要加上: readonly var 而若只打readonly則會列出所有唯讀的變數。還有一點,系統變數不可以設定 成唯讀的。 ┌———————┐│name=Tom ││readonly name ││echo $name ││name=John ││readonly │└———————┘結果如下:Tomname: is read onlyreadonly namereadonly ......4. 特殊變數 有些變數是一開始執行Script時就會設定,並且不以加以修改,但我們不叫它 唯讀的系統變數,而叫它特殊變數(有些書會叫它唯讀的系統變數),因為這 些變數是一執行程式時就有了,況且使用者無法將一般的系統變數設定成唯讀 的。以下是一些等殊變數: $0 這個程式的執行名字 $n 這個程式的第n個引數值,n=1..9 $* 這個程式的所有引數 $# 這個程式的引數個數 $$ 這個程式的PID $! 執行上一個背景指令的PID $? 執行上一個指令的返回值 當你執行這個程式時的引數數目超過9 個時,我們可以使用shift 命令將引數 往前移一格,如此即可使用第10個以後的引數。除此之外,吾人可以用set 命 令改變$n及$*,方法如下: set string 如此$*的值即為string,而分解後則會放入$n。如果set 命令後面沒有引數, 則會列出所有已經設定的變數以及其值。 檔名:ex1 引數:this is a test ┌———————————┐│echo Filename: $0 ││echo Arguments: $* ││echo No. of args.: $# ││echo 2nd arg.: $2 ││shift ││echo No. of args.: $# ││echo 2nd arg.: $2 ││set hello, everyone ││echo Arguments: $* ││echo 2nd arg.: $2 │└———————————┘結果如下:Filename: ex1Arguments: this is a testNo. of args.: 42nd arg.: isNo. of args.: 32nd arg.: aArguments: hello, everyone2nd arg.: everyone值得一提的是,當你想從鍵盤輸入一變數值時,你可以使用下面的命令: read var1 var2..... 這時read會將一個字分給一個變數。如果輸入的字比變數還多,最後一個變數會將剩下的字當成其值。如果輸入的字比變數還少,則後面的變數會設成空字串。 如果需要處理數值運算,我們可以使用expr命令。其引數及輸出列於附錄A。 二、執行命令 在Bourne Shell中有五種方法執行一個命令,而這五種方式所產生的果有些許的不 同。 1. 直接下命令 這個方式和在命令列中直接下命令的效果一樣。 2. 使用sh命令 sh command 這個檔案必須是Bourne Shell的Script,但這個檔案並不一定要設成可執行。 除此之外和直接下命令的方式一樣。 3. 使用"."命令 . command 這時和使用sh命令相似,只不過它不像sh一般會產生新的process ,相反地, 它會在原有的process 下完成工作。 4. 使用exec命令 exec command 此時這個Script將會被所執行的命令所取代。當這個命令執行完畢之後,這個 Script也會隨之結束。 5. 使用命令替換 這是一個相當有用的方法。如果想要使某個命令的輸出成為另一個命令的引數 時,就一定要使用這個方法。我們將命令列於兩個"`" 號之間,而Shell 會以 這個命令執行後的輸出結果代替這個命令以及兩個"`" 符號。 str='Current directory is '`pwd` echo $str 結果如下: Current directory is /users/cc/mgtsai 這個意思是pwd 這個命令輸出"/users/cc/mgtsai",而後整個字串代替原 來的`pwd` 設定str 變數,所以str 變數的內容則會有pwd 命令的輸出。 number=`expr $number + 1` 這就是先前所提要作數值運算的方法,基本上expr命令只將運算式解,而 後輸出到標準輸出上。如果要將某變數設定成其值,非得靠命令替換的方 式不可。這個例子是將number變數的值加1 後再存回number變數。 三、流程控制 在介紹流程控制之前,我們先來看看test命令。test命令的引數是條件判斷式,當 條件為真時則傳回非零值,而條件為偽時則傳回零。在所有的流程控制都必須用到 test命令來判斷真偽。而test命令的使用方法則列於附錄B。 test $# = 0 如果執行這個程式沒有引數時,會傳回非零值代表"$# = 0"這個條件成立。反 之則會傳回零。 以下介紹各種流程控制: 1. if then語法以及流程圖如下 │ FALSEif (condition) <condition>—┐then │TRUE │then-commands then-commands │fi ├————┘│condition 是一個test命令。往後所介紹的各種流程中的condition 都是test 命令。 檔名:chkarg ┌———————————┐│if (test $# != 0) ││ then ││ echo Arg1: $1 ││fi │└———————————┘$ chkarg HelloArg1: Hello$ chkarg$2. if then else語法以及流程圖如下 │ FALSEif (condition) <condition>—————┐then │TRUE │then-commands then-commands else-commandselse ├————————┘else-commands │fi3. if then elif語法以及流程圖如下 │ FALSEif (condition1) <condition1>—┐then │TRUE │ FALSEcommands1 commands1 <condition2>—┐elif (condition2) │ │ TRUE │then │ commands2 commands3commands2 ├—————┴————┘else │commands3commands3fiecho 'word 1: c'read word1echo 'word 2: c'read word2echo 'word 3: c'read word3if (test "$word1" = "$word2" -a "$word2" = "$word3")thenecho 'Match: words 1, 2, & 3'elif (test "$word1" = "$word2")thenecho 'Match: words 1 & 2'elif (test "$word1" = "$word3")thenecho 'Match: words 1 & 3'elif (test "$word2" = "$word3")thenecho 'Match: words 2 & 3'elseecho 'No match'fi4. for in語法以及流程圖如下 │ FALSEfor var in arg-list ┌—<arg-list還有東西嗎?>—┐do │ │TRUE │commands │ 從arg-list取得一項 │done │ 放到變數var ││ │ ││ commands │└——————┘ │┌———————————┐ ┌—————┘│for a in xx yy zz │ ││ do ││ echo $a ││done │└———————————┘結果如下:xxyyyyzz5. for語法以及流程圖如下 │ FALSEfor var ┌—<引數中還有東西嗎?>—┐do │ │TRUE │commands │ 從引數中取得一項 │done │ 放到變數var ││ │ ││ commands │└—————┘ │檔名:lstarg ┌—————┘┌———————————┐ ││for a ││ do ││ echo $a ││done │└———————————┘$lstarg xx yy zzxxyyyyzz6. while 語法以及流程圖如下 │ FALSEwhile (condition) ┌—<condition>—┐do │ │TRUE │commands │ commands │done └————┘ │┌————┘│┌———————————————┐│number=0 ││while (test $number -lt 10) ││ do ││ echo "$numberc" ││ number=`expr $number + 1` ││done ││echo │└———————————————┘結果如下:01234567897. until語法以及流程圖如下 │ TRUEuntil (condition) ┌—<condition>—┐do │ │FALSE │commands │ commands │done └————┘ │┌————┘│它和while 的不同只在於while 是在條件為真時執行迴圈,而until 是在條件 為假時執行迴圈。 8. break及continue 這兩者是用於for, while, until 等迴圈控制下。break 會跳至done後方執行 ,而continue會跳至done執行,繼續執行迴圈。 9. case語法以及流程圖如下 │ TRUEcase str in <str=pat1>————commands1—┐pat1) commands1;; │FALSE TRUE │pat2) commands2;; <str=pat2>————commands2—┤pat3) commands3;; │FALSE TRUE │esac <str=pat3>————commands3—┤│FALSE │├————————————┘│而pat 除了可以指定一些確定的字串,也可以指定字串的集合,如下 * 任意字串 ? 任意字元 [abc] a, b, 或c三字元其中之一 [a-n] 從a到n的任一字元 | 多重選擇 ┌———————————————┐│echo 'Enter A, B, or C: c' ││read letter ││case $letter in ││ A|a) echo 'You entered A.';;││ B|b) echo 'You entered B.';;││ C|c) echo 'You entered C.';;││ *) echo 'Not A, B, or C';; ││esac │└————————
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-944811/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Bourne Shell及shell程式設計(轉)程式設計
- Linux 程式設計之Shell程式設計(轉)Linux程式設計
- shell程式設計幫助(轉)程式設計
- BASH SHELL 程式設計簡介(轉)程式設計
- BASH Shell的指令碼程式設計(轉)指令碼程式設計
- Linux的shell程式設計(一)(轉)Linux程式設計
- Linux的shell程式設計(二)(轉)Linux程式設計
- Linux的shell程式設計(三)(轉)Linux程式設計
- Linux的shell程式設計(四)(轉)Linux程式設計
- shell程式設計程式設計
- Linux Shell程式設計(1)——shell程式設計簡介Linux程式設計
- Shell程式設計 --- Shell介紹程式設計
- 玩轉Linux – shell 程式設計基礎Linux程式設計
- 幾個shell程式設計小知識(轉)程式設計
- Windows Shell 程式設計Windows程式設計
- shell程式設計二程式設計
- shell程式設計五程式設計
- Shell程式設計-shell變數1程式設計變數
- Linux下的shell程式設計入門(轉)Linux程式設計
- Shell程式設計-02-Shell變數程式設計變數
- Linux Shell程式設計(27)——子shellLinux程式設計
- 初識shell程式設計程式設計
- Shell 程式設計入門程式設計
- shell程式設計進階程式設計
- shell程式設計入門程式設計
- Shell程式設計-基礎程式設計
- shell併發程式設計程式設計
- linux shell 程式設計Linux程式設計
- linux shell程式設計Linux程式設計
- 戀上shell程式設計程式設計
- Oracle-SHELL程式設計Oracle程式設計
- shell程式設計簡介程式設計
- shell vbscript xml程式設計XML程式設計
- shell 程式設計簡記程式設計
- shell程式設計基礎程式設計
- shell簡介入門bash程式設計之執行(轉)程式設計
- Shell程式設計-11-子Shell和Shell巢狀程式設計巢狀
- Linux Shell程式設計(2)——第一個shell程式Linux程式設計