Chinaunix首页 | 论坛 | 博客
  • 博客访问: 851395
  • 博文数量: 190
  • 博客积分: 7021
  • 博客等级: 少将
  • 技术积分: 1752
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-17 19:26
文章分类

全部博文(190)

文章存档

2014年(9)

2011年(32)

2010年(149)

我的朋友

分类: LINUX

2010-06-30 14:17:57

當我們對 shell 變數和命令行有一定認識之後﹐那麼﹐我們就可以嘗試寫自己的 shell script 囉~~ 這可是非常好玩而又有成就感的事情呢﹗^_^

在 linux 裡面的 shell script 可真是無處不在﹕我們開機執行的 run level 基本上都是一些 script ﹔登錄之後的環境設定﹐也是些 script ﹔甚至工作排程和記錄維護也都是 script 。您不妨隨便到 /etc/rc.d/init.d 裡面抓兩個程式回來看看﹐不難發現它們都有一個共同的之處﹕第一行一定是如下這樣的﹕

#!/bin/sh
或﹕
#!/bin/bash

其實﹐這裡的 #! 後面要定義的就是命令的解釋器(command interpreter)﹐如果是 /bin/bash 的話﹐那下面的句子就都用 bash 來解釋﹔如果是 /usr/bin/perl 的話﹐那就用 perl 來解釋。不同的解釋器所使用的句子語法都不一樣﹐非常嚴格﹐就算同是用 shell 來解釋﹐不同的 shell 之間的格式也不僅相同。所以﹐如果您看到 script 的解釋器是 /bin/sh 的話﹐那就要小心了﹕如果您仔細看這個檔案﹐事實上它僅是一個 link 而已﹐有些系統或許會將它 link 到其它 shell 去。假如您的 script 句子使用的語法是 bash 的話﹐而這個 sh 卻 link 到 csh ﹐那執行起來可能會有問題。所以﹐最好還是直接指定 shell 的路徑比較安全一些﹕在這裡的範例都使用 /bin/bash 來作為 script 的解釋器。

在真正開始寫 script 之前﹐先讓我們認識 script 的一些基本概念﹕

簡單來說﹐shell script 裡面就是一連串命令行而已﹐再加上條件判斷﹑流程控制﹑迴圈﹑等技巧﹐聰明地執行正確的命令和使用正確的參數選項。和我們在 shell 裡面輸入命令一樣﹐shell script 也有這樣的特性﹕

  • 當讀到一個 CR 字符的時候﹐就嘗試執行該行命令﹔
  • 它會忽略空白行﹔句子前面的空白和 tab 也不理會﹔
  • CR 字符也同樣可以用“ \ ”符號跳脫﹔
  • 另外﹐“ # ”符號是註解符號﹐從這個符號至句子末端的內容全被忽略﹐程式本身不會讀入這部份﹐但我們經常用來給使用者閱讀﹐因而名為註解﹔
  • 等等。

一個良好的 script 作者﹐在程式開頭的時候﹐都會用註解說明 script 的名稱﹑用途﹑作者﹑日期﹑版本﹑等信息。如果您有這個機會寫自己的 script﹐也應該有這個良好習慣。

shell script 檔的命名沒一定規則﹐可以使用任何檔案名稱(參考檔案系統)﹐但如果您喜歡的話﹐可以用 .sh 來做它的副檔名﹐不過這不是硬性規定的。不過﹐要執行一個 shell script﹐使用者必須對它有執行權限( x )﹐用文件編輯器新建立的檔案都是沒有 x permission 的﹐請用 chmod 命令加上。執行的時候﹐除非該 script 已經至於 PATH 環境變數之內的路徑內﹐否則您必須指定路徑。例如﹐您寫了一個叫 test.sh 的 shell script﹐放在家目錄內﹐假設這也是您的當前工作目錄﹐您必須加上路徑才能執行﹕./test.sh 或 ~/test.sh 。所以﹐建議您在 script 測試無誤之後﹐放在 ~/bin 目錄裡面﹐那就可以在任何地方執行自己的 script 了﹐當然﹐您要確定 ~/bin 已經出現在您的 PATH 變數裡面。

script 之所以聰明﹐在於它能夠對一些條件進行測試( test )。您可以直接用 test 命令﹐也可以用 if 敘述﹐例如﹕test -f ~/test.sh 。它的意思是測試一下 ~/test.sh 這個檔案是否存在﹐這個 -f 通常用在檔案上面的測試﹐除了它﹐還有很多﹕

標籤代表意思
-G存在﹐並且由 GID 所執行的行程所擁有。
-L存在﹐並且是 symbolic link 。
-O存在﹐並且由 UID 所執行的行程所擁有。
-S存在﹐並且是一個 socke 。
-b存在﹐並且是 block 檔案﹐例如磁碟等。
-c存在﹐並且是 character 檔案﹐例如終端或磁帶機。
-d存在﹐並且是一個目錄。
-e存在。
-f存在﹐並且是一個檔案。
-g存在﹐並且有 SGID 屬性。
-k存在﹐並且有 sticky bit 屬性。
-p存在﹐並且是用於行程間傳送資訊的 name pipe 或是 FIFO。
-r存在﹐並且是可讀的。
-s存在﹐並且體積大於 0 (非空檔)。
-u存在﹐並且有 SUID 屬性。
-w存在﹐並且可寫入。
-x存在﹐並且可執行。

事實上﹐關於這些測試項目還有很多很多﹐您可以 man bash 然後參考 CONDITIONAL EXPRESSIONS 那部份。另外﹐我們還可以同時對兩個檔案進行測試﹐例如﹕test file1 -nt file2 就是測試 file1 是否比 file2 要新。這種測試使用的標籤是﹕

標籤代表意思
-ntNewer Than﹕第一個檔案比第二個檔案要新。
-otOlder Than﹕第一個檔案比第二個檔案要舊。
-efEqual File﹕第一個檔案和第二個檔案其實都是同一個檔案 (如 link)。

我們這裡所說的這些測試﹐不單只用來測試檔案﹐而且還常會用來比對‘字串 (string)’或數字(整數)。那什麼是字串呢﹖字面來介紹就是一串文字嘛。在一個測試中﹐~/test.sh 本身是一個檔案﹔但 '~/test.sh' ﹐則是在引號裡面(單引號或雙引號)﹐那就是字串了。

在數字和字串上面的比對(或測試)﹐所使用的標籤大約有﹕

標籤代表意思
=等於
!=不等於
<小於
>大於
-eq等於
-ne不等於
-lt小於
-gt大於
-le小於或等於
-ge大於或等於
-a雙方都成立
-o單方成立
-z空字串
-n非空字串

在上面提到的比對中﹐雖然有些意思一樣﹐但使用場合卻不盡相同。例如 = 和 -eq 都是‘等於’的意思﹐但 = 只能比對字串﹐而 -eq 則可以用來比對字串﹐也能用來比對表示色樣(我們在 regular expression 會碰到)。

我們之所以要進行測試或比對﹐主要是用來做判斷的﹕假如測試或比對成立﹐那就返回一個‘真實 (true)’否則返回‘虛假 (false)’。也就是說﹕如果條件成立那麼就會如何如何﹔如果條件不成立又會如何如何﹐從而讓 script 有所‘智慧’。基本上﹐我們的程式之所以那麼聰明﹐都是從這些簡單到複雜的判斷開始的。

比方說﹐上面的 -a (AND) 和 -o (OR) 是用來測試兩個條件﹕A 和 B 。如果使用 test A -a B ﹐那麼 A 和 B 都必須成立那條件才成立﹔如果使用 test A -o B ﹐那麼只要 A 或 B 成立那條件就成立。至於其它的比對和測試﹐應該更好理解吧﹖

另外﹐還有一個特殊符號﹕“ !”您可不能不會運用。它是‘否’的意思﹐例如﹕"! -f"是非檔案﹔ "-ne" 和 "! -eq" 都是‘不等於’的意思。

我們在命令行上面已經知道如何定義和改變一個變數﹐那在 shell script 裡面就更是司空見慣了。而且﹐越會利用變數﹐您的 script 能力就越高。在 shell script 中所定義的變數有更嚴格的定義﹕

標籤代表意思
-a定義為陣列 (array) 變數
-f僅定義功 (function) 能名稱。
-i定義為整數。
-r定義為唯獨變數。
-x透過環境輸出變數。

我們除了用 “ = ”來定義變數之外﹐還可以用 declare 命令來明確定義變數。例如﹕

A=3 B="-2" 
RESULT=$A*$B 
echo $RESULT 
3*-2 
declare -i A=3 B="-2" 
declare -i RESULT=$A*$B 
echo $RESULT 
-6

您這裡會發現﹕如果沒有使用 declare 命令將變數定義為整數的話﹐那麼 A 和 B 的變數值都只是字串而已。

阅读(1353) | 评论(0) | 转发(0) |
0

上一篇:Bash 設定

下一篇:vim的配置

给主人留下些什么吧!~~