正是因為我們可以通過程序腳本,設計邏輯交給計算機幫助人類處理問題,才有了如今發(fā)展壯大的CS產(chǎn)業(yè)。shell script作為一個小程序語言,也是可以加入各種邏輯的,今天學習如何在shell script中加入判斷式(很簡單的)~~
首先,要學習一些邏輯判斷符號:這里通過如下“test指令的測試功能”學習,里面一些邏輯判斷(例如-o,-a)是不局限于test的,可以在shell中靈活應用。
1.test指令的測試功能
1.1 關于某個檔名的“文本類型”判斷
如teat -e filename 表示filename存在與否
| 測試的標志 | 代表意義 |
|---|---|
| -e | 該檔名是否存在? |
| -f | 該檔名是否存在且為文件(file)? |
| -d | 該文件名是否存在且為目錄(directory)? |
| -b | 該檔名是否存在且為一個block device裝置? |
| -c | 該檔名是否存在且為一個character device裝置? |
| -S | 該檔名是否存在且為一個Socket文件? |
| -p | 該檔名是否存在且為一個FIFO(pipe)文件? |
| -L | 該檔名是否存在且為一個鏈接檔? |
1.2關于文件的權限偵測
如test -r filename 表示filename是否可讀
| 測試的標志 | 代表意義 |
|---|---|
| -r | 偵測該檔名是否存在且具有可讀的權限? |
| -w | 偵測該檔名是否存在且具有可寫的權限? |
| -x | 偵測該檔名是否存在且具有可執(zhí)行的權限? |
| -u | 偵測該文件名是否存在且具有SUID的屬性? |
| -g | 偵測該文件名是否存在且具有SGID的屬性? |
| -k | 偵測該文件名是否存在且具有Sticky bit 的屬性? |
| -s | 偵測該檔名是否存在且為非空白文件? |
1.3 兩個文件之間的比較
如 test file1 -nt file2 判斷file1是否比file2新
| 測試的標志 | 代表意義 |
|---|---|
| - nt | (newer than)判斷file1是否比file2新 |
| -ot | (older than) 判斷file 1 是否比file2 舊 |
| -ef | 判斷 file1 與 file 2 是否為同一文件,可用在判斷hard link的判定上。主要意義在判定,兩個文件是否均指向同一個inode。 |
1.4 關于兩個整數(shù)之間的判定
如 test n1 -eq n2 判斷n1是否等于n2
| 測試的標志 | 代表意義 |
|---|---|
| -eq | 兩數(shù)值相等(equal) |
| -ne | 兩數(shù)值不等(not equal) |
| -gt | n1 大于 n2 (greater than) |
| -lt | n1 大于 n2 (less than) |
| -ge | n1 大于 n2 (greater than or equal) |
| -le | n1 小于等于 n2 (less than or equal) |
1.5 判定字符串的數(shù)據(jù)
| 測試的標志 | 代表意義 |
|---|---|
| test -z string | 判定字符串是否為0?若string為空字符串,則為true |
| test -n string | 判定字符串是否非?若string為空字符串,則為false(-n亦可省略) |
| test str1 == str2 | 判定str1是否等于str2,若相等,則回傳true |
| test str1 != str2 | 判定str1 是否不等于 str2,若相等,則回傳false |
1.6多重條件判定
如 test -r filename -a -x filename 判斷filename是否可讀且可執(zhí)行
| 測試的標志 | 代表意義 |
|---|---|
| -a | (and) 兩狀況同時成立,例如 test -r file -a -x file,則file同時具有r和x權限時,才回傳true |
| -o | (or)兩狀況任何一個成立! 例如test -r file -o -x file,則file具有r或x權限時就可回傳ture |
| ! | 反相狀態(tài),如test ! -x file ,當file不具有x時,回傳true |
我們寫個簡單的例子(注意利用test , ||, &&):
- 1)這個文件是否存在,若不存在則給予一個“filename does not exist” 的訊息,并中斷程序;
- 2)若這個文件存在,則判斷他是文件還是目錄?結果輸出“filename is a regular file” 或 “filename is directory”;
- 3)判斷一下,執(zhí)行者的身份對這個文件或目錄所擁有的權限,并輸出權限數(shù)據(jù)
先看一下這個 low low的寫法。。。
#!/bin/bash
read -p "請輸入文件名:" filename
test -e ${filename} && echo "exist" || echo "Not exist"
test -f ${filename} && echo "It is a file" || echo "It is not a file"
test -d ${filename} && echo "It is a directory" || echo "It is not a directory"
test -r ${filename} && echo "you can read " || echo "you can not read"
test -w ${filename} && echo "you can write " || echo "you can not write"
test -x ${filename} && echo "you can execute" || echo "you can not execute"
再看一下鳥哥的高端表達~~
vi file_perm.sh 輸入如下代碼:
#!/bin/bash
#1.讓使用者輸入檔名,并且判斷使用者是否真的有輸入字符串?
echo -e "Please input a filename, I will check the filename's type and permission"
read -p "Input a filename: " filename
test -z ${filename} && echo "You must input a filename." && exit 0
#2.判斷文件是否存在?若不存在則顯示訊息并結束腳本
test ! -e ${filename} && echo "The filename '${filename}' do not exist" && exit 0
#3.開始判斷文件類型與屬性
test -f ${filename} && filetype="regulare file"
test -d ${filename} && filetype="directory"
test -r ${filename} && perm="readable"
test -w ${filename} && perm="${perm} writable"
test -x ${filename} && perm="${perm} executable"
#4.開始輸出信息
echo "The filename: ${filename} is a ${filetype}"
echo "And the permission for you are : ${perm}"
2. 利用判斷括號[ ]
中括號[ ]學到現(xiàn)在可能有點眼花繚亂了, 因為之前學通配符和正則表達式時都有遇到過。
而在bash的語法中使用它作為shell的判斷式時,必須注意中括號的兩端要有空格符來分隔!如果空格鍵用口來表示。那么,這些地方都應該注意加空格鍵:

寫一段shell來練習:
- 1)當執(zhí)行一個程序的時候,這個程序會讓用戶選擇Y或N,
- 2)如果用戶輸入Y或y時,就顯示“OK,continue”
- 3)如果用戶輸入N或n時,就顯示“Oh,interrupt!”
- 4)如果不是Y/y/N/n之內(nèi)的其他字符,就顯示"I don't konw what your choice is"
Tip:
-- 這里判斷式內(nèi)要有2個判斷才行,因此判斷式內(nèi)的判斷連結需要使用-o
-- 同時,巧用exit 0來控制程序執(zhí)行
vi ans_yn.sh 輸入如下代碼:
#!/bin/bash
read -p "Please input 'Y' or 'N' to execute this program:" input
[ "${input}" == "Y" -o "${input}" == "y" ] && echo "OK,continue" && exit 0 #如果輸入"Y" 或 “y”,echo輸出后便退出程序
[ "${input}" == "N" -o "${input}" == "n" ] && echo "Oh,interrupt!" && exit 0 #如果輸入"N" 或 “n”,echo輸出后便退出程序
echo "I don't know what your choice is" && exit 0 #如果不是"Y","y","N","n"中的任何一個,程序才會走到這一步(這是前面兩步判斷式后面加`exit 0`的意義)
3. shell script 的默認變數(shù)
3.1 認識shell script 的默認變數(shù)($0,$1)
其實script針對參數(shù)已經(jīng)有設定好一些變量名稱了

執(zhí)行的腳本檔名為$0這個變量,第一個接的參數(shù)就是$1。所以,只要我們在script里面善用$1的話,就可以很簡單的立即下達某些指令功能了。
其他一些較為特殊的變量可以在script內(nèi)使用來呼叫這些參數(shù):
-
$#代表后接的參數(shù)(個數(shù)) -
$@代表 「“$1” “$2” “$3” “$4”」之意,每個變量是獨立的(用雙括號括起來) -
$*代表 「“$1c$2c$3c$4”」,其中c為分隔字符,默認為空格鍵,所以本例中代表「“$1 $2 $3 $4”」之意
還是來實例學習一下吧:執(zhí)行一個可以攜帶參數(shù)的script,執(zhí)行腳本后可以顯示如下內(nèi)容
- 1)程序的文件名為何?
- 2)共有幾個參數(shù)?
- 3)若參數(shù)的個數(shù)小于2則告知使用者參數(shù)數(shù)量太少
- 4)全部的參數(shù)內(nèi)容為何
- 5)第一個參數(shù)為何
- 6)第二個參數(shù)為何
vi how_paras.sh 輸入如下代碼:
#!/bin/bash
echo "程序的文件名為 ==> "$0""
echo "程序的參數(shù)個數(shù) ==> "$#""
[ "$#" -lt 2 ] && echo "參數(shù)的個數(shù)小于2"
echo "全部的參數(shù)內(nèi)容 ==> "$@""
echo "第一個參數(shù)為 ==> "$1""
echo "第二個參數(shù)為 ==> "$2""
3.2 shift:造成參數(shù)變量號碼偏移
shift會移動變量,而且shif 后面可以接數(shù)字,代表拿掉最前面的幾個參數(shù)的意思
還是從例子中理解吧
vim shift_paras.sh 輸入如下代碼:
#!/bin/bash
echo "程序的參數(shù)個數(shù) ==> “$#”"
echo "全部的參數(shù)內(nèi)容 ==> “$@”"
shift #第一次偏移(1個參數(shù))
echo "程序的參數(shù)個數(shù) ==> “$#”"
echo "全部的參數(shù)內(nèi)容 ==> “$@”"
shift 3 #第二次偏移(3個參數(shù))
echo "程序的參數(shù)個數(shù) ==> “$#”"
echo "全部的參數(shù)內(nèi)容 ==> “$@”"
執(zhí)行shift_paras.sh,看鳥哥執(zhí)行的結果吧
