|
Linux中的腳本編程2010-04-09 10:54 linux 下最重要的腳本語言算是 bash 了,我也就寫點(diǎn)這個吧(我也只會這個:))。跟其他開發(fā)語言(如C)比,bash 是比較簡單的一種語言,主要用于寫一些腳本代碼,一些批處理或安裝程序。你可以看看在/etc/init.d/目錄下,那里就有很多用來控制各個服務(wù)的腳 本文件。 先看一個“hello world!”的例子: 在某個目錄下新建一個文件,叫hello.sh,敲入以下代碼: #!/bin/sh echo "hello world!" 好,就這些。保存,在命令提示符下進(jìn)入保存“hello.sh”的目錄,這樣執(zhí)行: #sh hello.sh(回車) 看到了吧?哈哈,不過你高興的不要太早了,只并不能說明什么,就象你在其他編程環(huán)境中做的“hello world.”一樣,離高手的距離還遠(yuǎn)著呢。 我們先看看bash腳本中變量的使用。 修改上面的“hello world!”的例子,改成下面的樣子: #!/bin/bash # This is a very simple example str="hello world!" echo $ str 保存后按照上面的方法執(zhí)行該腳本,你將看到和以前一樣的效果。我們看看每一句的意義: 第一行,#! 是說明 hello.sh 這個文件的類型的,有點(diǎn)類似 Windows 系統(tǒng)下用文件后綴來表示不同文件類型的意思。Linux 系統(tǒng)根據(jù) "#!" 及該字串后面的信息確定該文件的類型。在 BASH 中第一行的 "#!" 及后面的 "/bin/bash" 就表明該文件是一個 BASH 程序,需要由 /bin 目錄下的 bash 程序來解釋執(zhí)行。BASH 這個程序一般是存放在 /bin 目錄下。這一行的寫法是固定的。 第二行的 "# This is a ..." 就是 BASH 程序的注釋,在 BASH 程序中從“#”號(沒有“!”號)開始到行尾的部分均被看作是程序的注釋,相當(dāng)于C/C++語言中的“//”。 第三行是為一個名稱為 str 的變量賦值。 第四行的 echo 語句的功能是把 echo 后面的字符串或變量的內(nèi)容輸出到標(biāo)準(zhǔn)輸出中去。需要注意的是 BASH 中的絕大多數(shù)語句結(jié)尾處都沒有分號。 對于第三行,可能有人會問:在C/C++中,變量都屬于某個類型,在這變量 str 的類型是什么呢?在 BASH 中變量定義是不需要的,沒有 "int i" 這樣的定義過程。如果想用一個變量,只要他沒有在前面被定義過,就直接可以用,當(dāng)然你使用該變量的第一條語句應(yīng)該是對他賦初值了,如果你不賦初值也沒關(guān) 系,只不過該變量是空(注意:是 NULL,不是 0 )。 關(guān)于變量的使用,要注意以下幾點(diǎn): 一,變量賦值時,“=”左右兩邊都不能有空格; 二,BASH 中的語句結(jié)尾不需要分號(";"); 三,除了在變量賦值和在FOR循環(huán)語句頭中,BASH 中的變量使用必須在變量前加"$ "符號。 在比較詳細(xì)的 bash 文檔中,會規(guī)定使用變量要采用這樣的形式:$ {STR},如果你的腳本出了莫名其妙的錯誤,不妨看看是不是這個問題造成的。 BASH 中的變量既然不需要定義,也就沒有類型一說,那是不是一個變量既可以存放整數(shù),也可以存放字符串呢?對! 一個變量即可以被定義為一個字符串,也可以被再定義為整數(shù)。如果對該變量進(jìn)行整數(shù)運(yùn)算,他就被解釋為整數(shù);如果對他進(jìn)行字符串操作,他就被看作為一個字符串。請看下面的例子: #!/bin/bash x=2006 let "x = $ x + 1" echo $ x x="a string." echo $ x 執(zhí)行一下看看? 又出現(xiàn)了新的關(guān)鍵字:let。關(guān)于整數(shù)變量計(jì)算,有如下幾種:" + - * / % ",他們的意思和字面意思相同,在*和/之前必須冠以反斜線,已防被SHELL先行解釋。整數(shù)運(yùn)算一般通過 let 和 expr 這兩個指令來實(shí)現(xiàn),如對變量 x 加 1 可以寫作:let "x = $ x + 1" 或者 x=`expr $ x + 1` 關(guān)于運(yùn)行時參數(shù),我們在執(zhí)行腳本時有時很想傳個參數(shù)進(jìn)去,如:#sh mysh.sh hdz(回車)好,很簡單,在 bash 中,使用這樣傳進(jìn)來的變量時也要在前面加“$ ”符號。 $ # 傳入腳本的命令行參數(shù)個數(shù); $ * 所有命令行參數(shù)值,在各個參數(shù)值之間留有空格; 位置變元 $ 0 命令本身(shell文件名) $ 1 第一個命令行參數(shù); $ 2 第二個命令行參數(shù); ... 好,編輯以下腳本: #!/bin/sh echo "number of vars:"$ # echo "values of vars:"$ * echo "value of var1:"$ 1 echo "value of var2:"$ 2 echo "value of var3:"$ 3 echo "value of var4:"$ 4 保存文件名為 my.sh,執(zhí)行時傳入?yún)?shù):#sh my.sh a b c d e(回車),看到結(jié)果你就會更清楚各個變量的意思。如果訪問的參數(shù)在執(zhí)行時沒有傳入,如有一條這樣的代碼: echo "value of var4:"$ 100 而在執(zhí)行時并沒有輸入100個參數(shù),那取得的值為 NULL。 在 BASH 程序中如果一個變量被使用了,那么直到該程序的結(jié)尾,該變量都一直有效。為了使得某個變量存在于一個局部程序塊中,就引入了局部變量的概念。BASH 中,在變量首次被賦初值時加上 local 關(guān)鍵字就可以聲明一個局部變量,如下面這個例子: #!/bin/bash HELLO="var1" echo $ HELLO function hello { local HELLO="var2" echo $ HELLO } echo $ HELLO 該程序的執(zhí)行結(jié)果是: var1 var2 var1 這個執(zhí)行結(jié)果表明全局變量 $ HELLO 的值在執(zhí)行函數(shù) hello 時并沒有被改變。也就是說局部變量 $ HELLO 的影響只存在于函數(shù)那個程序塊中。 BASH 中的變量與 C 語言中變量的區(qū)別 這里我們?yōu)樵瓉聿皇煜?BASH 編程,但是非常熟悉 C 語言的程序員總結(jié)一下在 BASH 環(huán)境中使用變量需要注意的問題。 1,BASH 中的變量在引用時都需要在變量前加上 "$ " 符號( 第一次賦值及在For循環(huán)的頭部不用加 "$ "符號 ); 2,BASH 中沒有浮點(diǎn)運(yùn)算,因此也就沒有浮點(diǎn)類型的變量可用; 3,BASH 中的整形變量的比較符號與 C 語言中完全不同,而且整形變量的算術(shù)運(yùn)算也需要經(jīng)過 let 或 expr 語句來處理; 下面我們來看看變量之間的比較操作: 在比較操作上,整數(shù)變量和字符串變量各不相同,詳見下表: 對應(yīng)的操作 整數(shù)操作 字符串操作 相同 -eq = 不同 -ne != 大于 -gt > 小于 -lt < 大于或等于 -ge 小于或等于 -le 為空 -z 不為空 -n 比如: 比較整數(shù) a 和 b 是否相等就寫做 if [ $ a = $ b ] 判斷整數(shù) a 是否大于整數(shù) b 就寫做 if [ $ a -gt $ b ] 比較字符串 a 和 b 是否相等就寫作:if [ $ a = $ b ] 判斷字符串 a 是否為空就寫作: if [ -z $ a ] 判斷整數(shù)變量 a 是否大于 b 就寫作:if [ $ a -gt $ b ] 注意:在“[”和“]”符號的左右都留有空格。 BASH 是 Linux 操作系統(tǒng)的 Shell,因此系統(tǒng)的文件必然是 BASH 需要操作的重要對象 運(yùn)算符,下面說說對文件的操作: 含義( 滿足下面要求時返回 TRUE ) -e 文件已經(jīng)存在 -f 文件是普通文件 -s 文件大小不為零 -d 文件是一個目錄 -r 文件對當(dāng)前用戶可以讀取 -w 文件對當(dāng)前用戶可以寫入 -x 文件對當(dāng)前用戶可以執(zhí)行 -g 文件的 GID 標(biāo)志被設(shè)置 -u 文件的 UID 標(biāo)志被設(shè)置 -O 文件是屬于當(dāng)前用戶的 -G 文件的組 ID 和當(dāng)前用戶相同 file1 -nt file2 文件 file1 比 file2 更新 file1 -ot file2 文件 file1 比 file2 更老 如 if [ -x /root ] 可以用于判斷 /root 目錄是否可以被當(dāng)前用戶進(jìn)入。 上面有進(jìn)行比較的 if 關(guān)鍵字,是的,bash 中有和 C 語言相似的流程控制語句,主要有:if、for、while、until、case 等語句。下面較詳細(xì)的介紹一下。 if 語句用于判斷和分支,其語法規(guī)則和 C 語言的 if 非常相似。其幾種基本結(jié)構(gòu)為: if [ expression_r ] then #code block fi 或者 if [ expression_r ] then #code block else #code block fi 或者 if [ expression_r ] then #code block else if [ expression_r ] then #code block else #code block fi 或者 if [ expression_r ] then #code block elif [ expression_r ] then #code block else #code block fi 如果您為了簡潔,想把 then 和 if 放在一行,那就要這樣寫了:if [ expression_r ]; then。即在 then 前加一個“;”號(bash 里面每行的結(jié)束處沒有分號,那要把兩行的內(nèi)容寫到一行,是不是要用“;”號隔開啊?哈哈,對!這樣說來,“if [ expression_r ]; then”只是把兩行內(nèi)容寫到了一行,沒有什么新的東西。)。 for 循環(huán)結(jié)構(gòu)與 C 語言中有所不同,在 BASH 中 for 循環(huán)的基本結(jié)構(gòu)是: for $ var in do #code block done 其中 $ var 是循環(huán)控制變量, 是 var 需要遍歷的一個集合,do/done 對包含了循環(huán)體,相當(dāng)于 C 語言中的一對大括號。另外如果do 和 for 被寫在同一行,必須在 do 前面加上 ";"。如: for $ var in ; do 。下面是一個運(yùn)用 for 進(jìn)行循環(huán)的例子: #!/bin/bash for day in Sun Mon Tue Wed Thu Fri Sat do echo $ day done # 如果列表被包含在一對雙引號中,則被認(rèn)為是一個元素 for day in "Sun Mon Tue Wed Thu Fri Sat" do echo $ day done exit 0 注意上面的例子中,在 for 所在那行的變量 day 是沒有加 "$ " 符號的,而在循環(huán)體內(nèi),echo 所在行變量 $ day 是必須加上 "$ " 符號的。另外如果寫成 for day 而沒有后面的 in 部分,則 day 將取遍命令行的所有參數(shù)。如這個程序: #!/bin/bash for param do echo $ param done exit 0 上面這個程序?qū)⒘谐鏊忻钚袇?shù)。for 循環(huán)結(jié)構(gòu)的循環(huán)體被包含在 do/done 對中,這也是后面的 while、until 循環(huán)所具有的特點(diǎn)。 while 循環(huán)的基本結(jié)構(gòu)是: while [ condition ] do #code block done 這個結(jié)構(gòu)請大家自己編寫一個例子來驗(yàn)證。 until 循環(huán)的基本結(jié)構(gòu)是: until [ condition is TRUE ] do #code block done 這個結(jié)構(gòu)也請大家自己編寫一個例子來驗(yàn)證。 case BASH 中的 case 結(jié)構(gòu)與 C 語言中的 switch 語句的功能比較類似,可以用于進(jìn)行多項(xiàng)分支控制。其基本結(jié)構(gòu)是: case "$ var" in condition1 ) ;; condition2 ) ;; * ) default statments;; esac 下面這個程序是運(yùn)用 case 結(jié)構(gòu)進(jìn)行分支執(zhí)行的例子: #!/bin/bash echo "Hit a key, then hit return." read Keypress case "$ Keypress" in [a-z] ) echo "Lowercase letter";; [A-Z] ) echo "Uppercase letter";; [0-9] ) echo "Digit";; * ) echo "Punctuation, whitespace, or other";; esac exit 0 上面例子中的第四行 "read Keypress" 一句中的 read 語句表示從鍵盤上讀取輸入。這個命令將在本講義的 BASH 的其他高級問題中講解。 break/continue 熟悉 C 語言編程的都很熟悉 break 語句和 continue 語句。BASH 中同樣有這兩條語句,而且作用和用法也和 C 語言中相同,break 語句可以讓程序流程從當(dāng)前循環(huán)體中完全跳出,而 continue 語句可以跳過當(dāng)次循環(huán)的剩余部分并直接進(jìn)入下一次循環(huán)。 關(guān)于bash在控制臺下的快捷鍵 ctrl+u 刪除光標(biāo)以前的所有字符 ctrl+d 刪除光標(biāo)以前的一個字符 ctrl+k 刪除光標(biāo)以后的所有字符 ctrl+h 刪除光標(biāo)以后的一個字符 ctrl+t 調(diào)換光標(biāo)前兩個字符的次序 ctrl+a 移動光標(biāo)到最前面 ctrl+e 移動光標(biāo)到最后面 ctrl+p 上一個命令 ctrl+n 下一個命令 ctrl+s 鎖定輸入 ctrl+q 解除鎖定 ctrl+f 移動光標(biāo)到后一個字符 ctrl+b 移動光標(biāo)到前一個字符 ctrl+x 標(biāo)記一個位置 ctrl+c 清除當(dāng)前的輸入 |
|
|