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 <
(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 <
相关阅读 更多 +