文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>UNIX Shell Programming

UNIX Shell Programming

时间:2007-01-12  来源:darrenshen

http://www.freebsd.org.hk/html/other/shell1.html   Chap 0 -- 前言 ( UNIX Shell Programming not for guru ...... )

(0.1) 讀者需要那些基礎 ?

這篇文章的主題是 UNIX Shell Programming . 閱讀這篇文章須要一點
基礎 , 包括 : 對 UNIX 的命令要有一點認識 , 尤其是常用 , 重要的
命令 . 此外 , 你也必需會在 UNIX 上使用 editor , 像 vi , joe 或
emacs 等 ...... 當然 , 假如你有寫程式的經驗 , 那麼 UNIX Shell
Programming 對你來說不過是反掌折枝罷了 .

(0.2) 使用那一種 Shell ? Why ?

既然 Shell 有很多種 , 我們所要介紹是最早由 AT&T Bell Labs 的
Stephen Bourne 所寫的標準 Shell , 也就是所謂的 Bourne Shell .
在一些情況下 , 也會順便提一下 C Shell 相關的東西 .

既然現在已經有了更新更好的 Shell , 那我們為什麼還要介紹 Bourne
Shell 呢? 這是因為 , 在 UNIX Shell Programming 中 , 有許多都
還是用 Bourne Shell 的語法寫成的 , 尤其像 /etc/rc.X ( SunOS )
而一般使用者或許用 C Shell 的增強版 tcsh 或 bash ( Bourne Again
Shell ) 這些比較新的 Shell . 不過沒有關係 , 只要系統中有 sh
( Bourne Shell ) 這個直譯器存在 , 那麼 , 我們都可以用 Bourne
Shell 的語法來寫程式 . ( 沒有 sh 的系統 , 是很難想像的 ...... )
還有一點 , 用 sh 來寫程式實際上比用 csh 要好 , 網路上已經有
討論過了 , 很多書也都提到用 csh 寫程式的缺點 , 並建議不要用
csh 來寫程式 . 我個人沒有什麼意見 , sh 與 csh 就好比程式語言
中的 Pascal 與 C (只是比喻) , 想必學過這兩種語言的人都知道 ,
只要學會了其中一種 , 另一種也不算太難學 , sh 與 csh 也是一樣 .
況且寫程式能真正作事就可以 , 不需要一下子用 sh , 一下子用 csh
來寫程式 .

*************************************************************

注意 !!!! 所有的例子都要在 Bourne Shell 系列的環境下操作
建議先看看 2.3 , 才不會搞了半天 , 才發覺原來你是用 C Shell
系列的 Shell (Shell 的種類及系列可參考 2.3)
此外 , 文中的一些例子都是在 Linux 下操作 , 在 SunOS 或 HP
上 , 命令也許有少許的不同 . 當你在演練時 , 假如不能正確的
執行 , 你應該看看指令的 manual . 像 SunOS 的 find 與 Linux
的 find 就有差異 . 大部份的例子都可以在各種不同的平臺上執行 .

*************************************************************

(0.3) 本篇文章的架構

本來想用 html 來寫的 , 這樣似乎比較好 , 但是覺得有點麻煩 , 所
以還是用平常的格式來寫 , 各位假如用 joe , 那麼當看到 (參考 x.y)
時 , 你還是可以用 ctrl-k f 來尋找 x.y 的標題 ; 在 vi 下也可以用
/x.y 來尋找 , 這樣也許也可以達到 hypertext 的效果吧 ...... :)

Chap 1 -- 簡介
Chap 2 -- 基本知識
Chap 3 -- Shell Programming 中的資料表示
Chap 4 -- Shell Programming 中的語法
Chap 5 -- 讀取資料及程式偵錯
附錄一 -- Shell Summary 及 一些 Shell Script 的例子
附錄二 -- grep 簡介及 regular expressions
參考資料 -- 介紹一些相關的書及資料

(0.4) 假如你已經對 Bourne Shell Programming 很熟 ......

那也許附錄一 Shell Summary 會對你有複習及快速參考的好處 !
還有 , 參考資料中的書目 , 都是值得一看的書 , 假如你還沒看過 ,
那我想你可以參考看看 . 當然 , man 及 grep 的配合 , 也常常
可以助你一臂之力 .

Chap 1 -- 簡介

無疑的 , UNIX 是一個功能強大的作業系統 , 它多人多工特性 , 網路
的支援 , 多采多姿的 X Windows System , 都相當的吸引人 . 除此之外
UNIX 還有一項重要的特性 , 就是它提供了數以百計的命令 .
每個人都知道 , DOS 下面也不過二三十個命令 , 這二三十個命令可能
一兩天就可以學的很好了 ; 但 UNIX 作業系統則不然 , 數百個命令就算
都學會了 , 若我們不知道如何去 "組合這些命令" , 那我們將失去學習
UNIX 的最大樂趣 !!

有人會覺得疑惑 : "組合命令"會有趣嗎 ? 什麼叫作 "組合命令" ?
這就是我們所要學習的 . 現在就舉一個最簡單的例子而言 : 請計算目前
工作目錄下共有多少個普通檔案 ( Regular File ) ?

當你遇到這樣的問題 , 你要如何解決 ? 有人會說 : " 我用 ls -l 列
出目前工作目錄下所有的檔案 , 然後慢慢的數 ...... " , 假如你用了
這樣的方法 , 而目前工作目錄下又有數百個檔案 , 那麼 , 我真的很敬
佩你 "愚公移山" 的精神 . 還有些人比較 "暴力" , 他說 : " 這個嘛
很簡單 , 我寫一個 C 語言程式 , 用 opendir , lstat 等函數來計算
某一目錄下有多少個普通檔案 ...... " 假如你要這樣做 , 那我當然不
反對 , 常練習寫程式也是不錯的 . 然而 , 就為了這麼小小的一個問題
而寫一段 C 語言的程式 , 未免太小題大作 . 實際上 , 解答的關鍵就
在 : " 你是不是會從數百個 UNIX 的命令中挑出適合的命令 , 然後把
這些命令組合起來 , 以達到我們所要的目的 !! " . " UNIX 的每個命令
就好比各種不同的 IC , 每種 IC 都有它特殊的作用 , 藉由不同 IC 的
組合 . 我們可以達到我們所要的功能 " , " 要達到目的的方法 , 常常
不是只有一種 ......" 上面這幾句話相當重要 , 各位現在也許還不清
楚 . 不過上面幾句話所提的 , 的確就是 UNIX 頗為吸引人的地方之一 .
除了命令之外 , Shell 提供了一些類似一般程式語言的語法 , 我們可
以利用這些語法來寫程式 . 而這點也正是本篇文章的最主要內容 .

Chap 2 -- 基本知識

(2.1) 什麼是 Shell ?

我們可以把 UNIX 切成兩方面來看 , 一部份是系統的核心 (kernel) ,
另一部份就是系統中的應用程式 . 舉凡我們常用的一些命令 , 像
ls , find 與 Shell 一樣 , 都可被歸類為應用程式 . 所以 , Shell
的地位與其它的應用程式並沒有什麼差別 .

我們可以看看簽入 UNIX 作業系統的過程 : 當我們輸入 username 之
後 , getty 就結束 , 取而代之的是 login . 在我們輸入正確的
password 後 , 系統就依照 /etc/passwd 中的記錄 , 為使用者啟動
相對應的 Shell . 在這個時候 , 使用者就會得到一個提示符號 .
接著我們就可以下達一些命令 .

--  getty --> login --> shell --> logout --
^                                          |
|------------------------------------------

Shell 有另一個名稱叫做 "命令列直譯器" (command interpreter)
從這個名稱當中 , 我們就可以了解到 Shell 實際上為命令列的翻譯官
當我們在提示符號後輸入一長串的命令 , 並按下 Enter 之後 , Shell
就將我們所輸入的東西 , 做一個適當的分析及處理 .

(2.2) Shell 負責的事

對系統做交談性的使用 . 包含了輸出輸入導向 ( 參考 2.5 ) ,
管線 ( 參考 2.6 ) Wildcard 的展開及匹配 ( 參考 2.4 ) , 另外
還有 Job Control( 從 SVR4 開始) , 變數環境設定?. 解譯命令 ....
還有一點很重要 , Shell 有它自己內建的程式語言 , 利用它的語法
我們可以來寫程式 , 寫出來程式功能並不像一般的程式語言 ( 如 C
語言 ) 那麼多 , 然而 , 在很多情況下就夠用了 . 這部份也就是整
篇文章的重點 .

(2.3) UNIX 系統上 Shell 的種類

在 DOS 中 , 想必各位一定都知道它的 Shell 為 command.com . 特別
要說明的是 : " Shell 是可以被置換掉的 ! " 所以 , 許多人在 DOS
中 , 常常把他們的 Shell 由 command.com 換成 4dos.com , 以得到
更多的功能 , 這已經是很平常的事了 . 在 UNIX 系統中也是一樣 ,
使用 chsh 這個命令 , 你可以挑你喜歡的 Shell 來使用 . 合法的
Shell 清單被列在 /etc/shells 這個檔案中 .

Shell 的種類可以分為兩個支派 , 一為由 Bourne Shell 衍生而來的
包括了 sh (Bourne Shell) , ksh (Korn Shell) , bash (Bourne
Again Shell) , zsh (Z Shell) ; 另一支派為 C Shell 衍生而來的 ,
包括了 csh , tcsh . 現在許多人作業的環境常常是在 csh 或 tcsh
之下 , 尤其是從 BSD 衍生而來 SunOS 的環境 .

你可以使用 echo $SHELL 來獲知你現在到底使用那一種 Shell . 或
者直接看 /etc/passwd 的最後一個欄位 .

(2.4) Wildcard 的展開及匹配

      Wildcard 有些人把它翻譯成 "萬用字元" , 下面所列舉的
      項目 , 並不盡然每一種 Shell 都支援 , 各位要自己試試看 .

(2.4.1) * : 代表任意的字串 ( 字串可以是空的 )

            % ls
            haha    haha1   haha2   memo1   memo13  memo2   memo23

            % ls haha*
            haha   haha1  haha2

            % ls memo*
            memo1   memo13  memo2   memo23

(2.4.2) ? : 代表任意一個字元

            % ls
            memo1   memo13  memo2   memo23

            % ls memo?
            memo1  memo2

            % ls memo1?
            memo13

(2.4.3) []: 代表符合[]中所列舉的字元

            % ls
            haha    haha1   haha2   memo1   memo13  memo2   memo23

            % ls memo[12]
            memo1  memo2

            [a-e]bc 會符合 abc , bbc , cbc , dbc , ebc  
             

(2.4.4) [!]: [] 中的字元 , 若加了 ! , 則表示不符合[]中所列舉的字元

            % ls
            haha    haha1   haha2   memo1   memo13  memo2   memo23

            % ls memo[!1]
            memo2

            [!a-z]bc 會符合不是以小寫英文字母開頭 , 後面接著 bc
            的字串 . 如會符合 : Cbc , 6bc 等 ......  

(2.4.5) {word1,word2....} : 如 my_{dog,cat,pig} 會符合 my_dog
         my_cat , my_pig
  

(2.4.6) \ : 接在 \ 之後的特殊字元 , 其特殊的意義會被取消
            例如 , 有一個檔案 , 它的名字真的叫 *abc , 那我們得用
            cat \*abc 才能把 *abc 中的內容顯示出來 .

(2.4.7) 更多關於 Wildcard 的討論 :

   (I)  glob : 這種 Wildcard 匹配的動作 , 我們稱為 " globbing "
        在很多種 Shell 之中都有一個叫作 noglob 的變數 , 可以把
        Wildcard 展開匹配的動作關掉 .  

        % ls *bc
        abc  bbc  cbc  dbc
               
        % set noglob   <-- C Shell 中設定變數的方法
                                   ( 設定變數參考 2.7)  

        % ls *bc
        ls: *bc: No such file or directory

  (II)  * 不會包含 . 開頭的檔案 , 要符合以 . 為開頭的檔案 , 你
        可以試試 .??* 或 .[!\.]*  ( For Newer Bourne Shell )
        .[^.]*  ( For tcsh )

(2.5) 輸出輸入導向

(2.5.1) Standard Input , Standard Output and Standard Error

在某方面來說 , 把資料寫到一個檔案中與寫到終端機並沒有什麼差別
相同的 , 把資料從檔案中讀出與從鍵盤讀出亦沒有什麼差別 .
在 UNIX 系統中 , 標準輸出輸入 ( Standard I/O ) 提供了一些預設
的輸出輸入設備 , 這些就是 stdin , stdout , 以及 stderr .

stdin : 一般說來 , 就是來自你鍵盤的輸入 , 但許多情況下 , 程式
        常忽略了 stdin , 而直接在命令列的參數中拿 . 如 :
        cat haha . haha 就可以當做 stdin .
stdout : 正常訊息輸出 , 預設是終端機 .
stderr : 錯誤訊息輸出 , 與 stdout 一樣 , 預設是終端機 .

stdin 的檔案描述值 ( file descriptor number ) 是 0 ,
stdout 是 1 , stderr 是 2 .

(2.5.2) 輸出輸入導向

舉一個最簡單的例子 , 我們用 ls -la 可列出目前目錄下所有的
內容 . 然而 , 若我們想要把終端機上的輸出放到一個檔案中 ,
那我們要如何做呢 ? 這時候 , 我們就要把原來終端機上的輸出
(也就是預設的標準輸出)導向至一個檔案 . 我們可以這樣作 :

ls -la > output_file

這個 > 的符號就是導向符號 .

下表是一般經常看到的輸出輸入導向 , prog 就是 program 的意思
而 file 就是一個檔案:

      功能                    sh,ksh,bash         csh,tcsh
--------------------------------------------------------------

把標準輸出導到一個檔案        prog > file         prog > file

把標準輸出導到檔案描述值 n    prog >&n

把原來輸出至檔案描述值 m      prog m>&n
的輸出與輸出至檔案描述值 n
的輸出 , 一起導向至檔案描
述值 n

把標準錯誤輸出導到一個檔案    prog 2> file

把標準輸出關閉                prog >&-

把標準輸出以及標準錯誤輸出    prog > file 2>&1    prog >& file
導到一個檔案

把標準輸出導到 f1 , 把標準   (prog > f1) 2>f2   (prog > f1) >& f2
錯誤輸出導到 f2

--------------------------------------------------------------

把標準輸出導到一個檔案的後面    prog >> file        prog >> file

把標準錯誤輸出導到一個檔案的    prog 2>> file
後面

把標準輸出以及標準錯誤輸出導    prog >> file 2>&1   prog >>& file
到一個檔案的後面

--------------------------------------------------------------

把檔案當作標準輸入            prog < file         prog < file

從檔案描述值 n 的地方讀取     prog <&n
當作 prog 的輸入          

把標準輸入關閉                prog <&-

--------------------------------------------------------------

把 file1 當成 prog 的標準     prog < file1 > file2
輸入 , 並把標準輸出的結果
再導向至 file2

--------------------------------------------------------------

從鍵盤的輸入當作 stdin , 直     prog <
相关阅读 更多 +
排行榜 更多 +
挖掘机卡车

挖掘机卡车

模拟经营 下载
我的汤姆猫小米版

我的汤姆猫小米版

模拟经营 下载
我的小小邮轮

我的小小邮轮

模拟经营 下载