Java之美[從菜鳥到高手演練]之Linux下shell指令碼的使用(一),javashell
作者:二青
個人網站:zhangerqing.cn 郵箱:xtfggef@gmail.com 微博:http://weibo.com/xtfggef
Shell指令碼就是將很多條命令結合起來寫在一起,通過運算以及判斷來實現很多功能的文本。為什麼學習shell,首先一些常規的系統管理操作,並且需要自動化地執行,如果用shell指令碼把這些操作集中在一起,只需要週期性執行這個shell指令碼就可以了,其次,對於一些複雜的文本處理,比如日誌分析等等,可能需求比較多,單條執行命令不是很方便,因此也需要使用shell實現,所以,如果想學通linux系統,shell是必備的一課。本章我們主要以bash shell為主,不涉及其它shell。
HelloWorld第一個shell指令碼,輸出Hello World。
第一行必須是#!/bin/bash(聲明我們用的是bash shell,否則系統不知道需要調用那個shell去執行指令碼)。由#開始的表示注釋,後面的字元在執行的時候全部被忽略。主體就是第4行的echo -e “Hello World \a \n”,-e表示啟用反斜線轉義, \a表示輸出“咚”的聲音,\n表示換行。寫完指令碼後,為指令碼添加可執行許可權:chmod +x sh01.sh,然後用./sh01.sh執行就好了。
互動式指令碼
最簡單的情況就是擷取使用者輸入,然後輸出。
這個例子也比較簡單,實用read進行輸入的擷取,並將值賦於緊跟著的變數上,執行效果:
數值計算
bash shell僅支援整數的簡單加減乘除,需要用到$((express)),兩層小括弧內的express則為計算的運算式。
第七行採用declare的方式聲明一個變數sum,使用$(( ))的方式計算結果。
判斷式
1. test命令
檢查檔案是否存在:test -e filename && echo "Exist" || "Not exist",如果存在,會輸出Exist,否則Not exist. test命令有很多參數.
命令 |
參數 |
解釋 |
備忘 |
關於檔案類型的判斷, test -e filename |
test |
-e |
檔案名稱是否存在 |
常用 |
|
-f |
檔案名稱是否存在且為檔案 |
常用 |
|
-d |
目錄名是否存在且為目錄 |
常用 |
|
-b |
檔案名稱是否存在且為一個block device裝置 |
|
|
-c |
檔案名稱是否存在且為一個character device裝置 |
|
|
-S |
檔案名稱是否存在且為一個Socket裝置 |
|
|
-p |
檔案名稱是否存在且為一個FIFO檔案 |
|
|
-L |
檔案名稱是否存在且為一個串連檔案 |
|
關於檔案的許可權檢測,如test -r filename |
|
-r |
檔案名稱是否存在且具有可讀許可權 |
|
|
-w |
檔案名稱是否存在且具有可寫入權限 |
|
|
-x |
檔案名稱是否存在且具有可執行許可權 |
|
|
-u |
檔案名稱是否存在且具有SUID屬性 |
|
|
-g |
檔案名稱是否存在且具有SGID屬性 |
|
|
-k |
檔案名稱是否存在且具有Sticky bit屬性 |
|
|
-s |
檔案名稱是否存在且為非空白檔案 |
|
關於兩個檔案之間的比較,test file1 -nt file2 |
|
-nt |
newer than,判斷file1是否比file2新 |
常用 |
|
-ot |
older than,判斷file1是否比file2舊 |
|
|
-ef |
判斷file1與file2是否為同一檔案 |
|
關於兩個整數之間的比較,test n1 -eq n2 |
|
-eq |
兩數值相等 |
|
|
-ne |
兩數值不等 |
|
|
-gt |
greater than,n1 大於n2 |
|
|
-lt |
less than,n1小於n2 |
|
|
-ge |
greater than or equal,n1 大於等於n2 |
|
|
-le |
less than or equal,n1小於等於n2 |
|
判斷字串 |
|
test -z string |
判斷字串是否為0 |
|
|
test -n string |
判斷字串是否不為0 |
|
|
test str1 = str2 |
判斷字串是否相等 |
|
|
test str1 != str2 |
判斷字串是否不等 |
|
多重條件判定,test -r filename -a -x filename |
|
-a |
兩個條件同時成立時返回true |
|
|
-O |
任何一個條件成立時返回true |
|
|
! |
反向狀態,當條件不成立時返回true |
|
2. []判斷符
除了使用test外,我們還可以使用[](中括弧)來進行一些判斷,如判斷HOME環境變數是否為空白:
[ -z $HOME ] ; echo $?
注意命令中的空格,[之後]之前都要跟一個空格,如果用到==,則==兩側也都需要有一個空格(要麼都有,要麼都沒有)。比如,[ "aaa" == "bbb" ],這是合理的方式,如果寫成[ "aaa" =="bbb" ]或者[ "aaa"== "bbb" ]就不合理了,會報錯。使用[]進行判斷時,應該注意如下幾點:
a. 在括弧[]內的組件都需要空格來分隔。
b. 括弧內的變數最好要用雙引號括起來。
c. 括弧內的常量最好也要用單引號或者雙引號括起來。
3. shell script的預設變數$0, $1, $2...
當我們給一個指令碼帶參數運行時,我們可以在指令碼裡擷取到該命令的一些資訊,比如:sh01.sh aaa bbb,在指令碼裡,$0就可以拿到指令碼名,$1,$2分別為第一、第二個參數,以此類推,我們可以總結一下:
$0, 指令碼名
$1, $2,指令碼的參數
$#, 參數個數
$@, 所有參數,每個參數用雙引號括起來
$*, 所有參數,用空格隔開
做個例子:
運行結果:
條件判斷式
這個好理解,就是我們常見的if else語句,在shell指令碼裡用if then表示if語句,if then else表示if else語句,if出現時要用fi來結尾,else if用elif代替。看個例子:
1. 判斷輸入的第一個參數是不是hello
2. 如果無任何參數,則提示使用者輸入一個參數
3. 如果輸入的參數不是hello,則提示使用者只能輸入hello作為參數
查看效果:
case判斷
我們用過程式語言裡的switch case語句,在某些情況下比if else方便很多,在shell指令碼裡也有類似的語句塊叫:case in esac,還是上面的例子,我們換種寫法:
看看效果:
迴圈
1. while do ... done
這個就是我們常見的while迴圈,當滿足條件時,已知執行迴圈體裡的語句,直到條件不滿足時推出迴圈,done為迴圈結束標誌。
2. until do ... done
該語句和while do ... done正好相反,當條件不滿足時進行迴圈,滿足時結束迴圈。
3. for do ... done
常見的for迴圈,一般就是對一個已知的數組或者結構進行迴圈遍曆。
for do ... done還有一種用法就是對數值的處理,可以使用我們傳統for迴圈的方式: for (( ;;))
shell 指令碼的追蹤與調試
在執行一個shell指令碼之前,我們可以先進行一系列的語法檢查,這樣可以初步檢測出一些明顯的問題。
sh [-nvx] script.sh
-n, 不執行script,僅檢查文法問題
-v, 在執行script前,先輸出指令碼到螢幕上
-x, 將使用到的script顯示到螢幕上,列出所有的執行過程
這一章基本就要結束了,主要是一些基本的編寫shell script的文法,我們可以先把這些掌握熟了,多加練習,然後多看一些複雜的文本處理的例子,多學習,多模仿複雜指令碼的寫法,然後寫出複雜的指令碼就不再是什麼難事。