鳥哥的Linux私房菜讀書筆記--判斷式
1、利用test指令的測試功能
命令:$ test -e 檔案絕對路徑 ##測試檔案是否存在。此命令不顯示資訊,我們可以通過 $? 或 && 及 ||來展現結果如下
命令:$ test -e 檔案絕對路徑 && echo "exist" || echo "no exist"
測試的標誌 | 代表意義 |
---|---|
1. 關於某個檔名的『檔案型別』判斷,如 test -e filename 表示存在否 | |
-e | 該『檔名』是否存在?(常用) |
-f | 該『檔名』是否存在且為檔案(file)?(常用) |
-d | 該『檔名』是否存在且為目錄(directory)?(常用) |
-b | 該『檔名』是否存在且為一個 block device 裝置? |
-c | 該『檔名』是否存在且為一個 character device 裝置? |
-S | 該『檔名』是否存在且為一個 Socket 檔案? |
-p | 該『檔名』是否存在且為一個 FIFO (pipe) 檔案? |
-L | 該『檔名』是否存在且為一個連結檔? |
2. 關於檔案的許可權偵測,如 test -r filename 表示可讀否 (但 root 許可權常有例外) | |
-r | 偵測該檔名是否存在且具有『可讀』的許可權? |
-w | 偵測該檔名是否存在且具有『可寫』的許可權? |
-x | 偵測該檔名是否存在且具有『可執行』的許可權? |
-u | 偵測該檔名是否存在且具有『SUID』的屬性? |
-g | 偵測該檔名是否存在且具有『SGID』的屬性? |
-k | 偵測該檔名是否存在且具有『Sticky bit』的屬性? |
-s | 偵測該檔名是否存在且為『非空白檔案』? |
3. 兩個檔案之間的比較,如: test file1 -nt file2 | |
-nt | (newer than)判斷 file1 是否比 file2 新 |
-ot | (older than)判斷 file1 是否比 file2 舊 |
-ef | 判斷 file1 與 file2 是否為同一檔案,可用在判斷 hard link 的判定上。 主要意義在判定,兩個檔案是否均指向同一個 inode 哩! |
4. 關於兩個整數之間的判定,例如 test n1 -eq n2 | |
-eq | 兩數值相等 (equal) |
-ne | 兩數值不等 (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) |
5. 判定字串的資料 | |
test -z string | 判定字串是否為 0 ?若 string 為空字串,則為 true |
test -n string | 判定字串是否非為 0 ?若 string 為空字串,則為 false。注: -n 亦可省略 |
test str1 == str2 | 判定 str1 是否等於 str2 ,若相等,則回傳 true |
test str1 != str2 | 判定 str1 是否不等於 str2 ,若相等,則回傳 false |
6. 多重條件判定,例如: test -r filename -a -x filename | |
-a | (and)兩狀況同時成立!例如 test -r file -a -x file,則 file 同時具有 r 與 x 許可權時,才回傳 true。 |
-o | (or)兩狀況任何一個成立!例如 test -r file -o -x file,則 file 具有 r 或 x 許可權時,就可回傳 true。 |
! | 反相狀態,如 test ! -x file ,當 file 不具有 x 時,回傳 true |
例:首先,判斷一下,讓使用者輸入一個檔名,我們判斷:
(1) 這個檔案是否存在,若不存在則給予一個『Filename does not exist』的訊息,並中斷程式;
(2) 若這個檔案存在,則判斷他是個檔案或目錄,結果輸出『Filename is regular file』或 『Filename is directory』
(3) 判斷一下,執行者的身份對這個檔案或目錄所擁有的許可權,並輸出許可權資料!
#!/bin/bash
#program
# user input a dilename ,program will check the flowing
# 1>exist 2>file/directory 3>file permissions
#history
# 20181010 lile first release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/temp
export PATH
echo -e "please input a filename ,I will check the filename's type and permission\n\t"
read -p "filename:" filename
test -z ${filename} && echo "you nust input a filename" && exit 0
test ! -e ${filename} && echo "the filename '${filename}'don't exist" && exit 0
#測試輸入檔名
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} execuated"
#測試檔案屬性
echo "the filename :${filename} is a ${filetype}"
echo "and the permissions for you are :${perm}"
上述指令碼執行時需要輸入指令碼的絕對路徑,即我們可以切換到其他目錄查詢相關的檔案,但是在使用source命令時需要輸入完整的指令碼檔案路徑。注意,由於root許可權在很多限制上面都是無效的,所以使用root執行這個指令碼時,其與ls命令觀察到的結果並不相同。建議使用執行者來執行該命令
2、利用判斷符號[]
使用判斷符號來進行資料的判斷,例如我想知道${HOME}變數是否為空
命令: $ [ -z "{HOME}"] ; echo $? ##中括號的兩端需要用空格(□)進行分隔
[ "$HOME" == "$MAIL" ]
[□"$HOME"□==□"$MAIL"□]
↑ ↑ ↑ ↑
在bash當中= 與 == 結果是一樣的,但是在慣用的程式寫法中,一個等號代表變數的設定,兩個等號代表邏輯判斷之意。
注意:(1)在[ ]中的每個元件都需要空格鍵來分隔
(2)在中括號內的變數最好都以雙引號擴起來
(3)在中括號內的常數最好都以單引號或雙引號擴起來。
例: 當執行一個程式的時候,這個程式會讓使用者選擇 Y 或 N ; 如果使用者輸入 Y 或 y 時,就顯示『 OK, continue 』;如果使用者輸入 n 或 N 時,就顯示『 Oh, interrupt !』;如果不是 Y/y/N/n 之內的其他字元,就顯示『 I don't know what your choice is 』
利用中括號、 && 與 || 來繼續吧!
#!/bin/bash
#program
# this program shows the user's choice
#history
# 20181010 lile first release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/temp
export PATH
echo -e "you should enter Y or N\n"
read -p "please input Y/N to express your think:" yn
[ "${yn}" == "y" ] -o [ "${yn}" == "Y"] && echo "ok,will eontinue" && exit 2
[ "${yn}" == "n" ] -o [ "${yn}" == "N"] && echo "no.will stop" && exit 8
echo "I don't know whar your choice is " && exit 0
3、shell script的預設變數($0,$1……)
在指令中,我們可以使用引數與選項,那麼shell script 後面可不可以帶有引數呢?例如重啟網路
命令: $ file /etc/init.d/network ##使用file查詢後,系統告知該檔案是bash可執行的script
命令 : $ /etc/init.d/network restart ##重啟網路
命令 : $ /etc/init.b/network stop ##關閉網路
如果依據程式的執行給予一些變數去進行不用的任務時,可以使用read功能,但是read的缺陷是需要手動輸入一些判斷式。我們可以通過指令後面接引數,一個指令就能夠處理完畢而不需要再次加入一些變數行為。
/path/to/scriptname opt1 opt2 opt3 opt4 $0 $1 $2 $3 $4
執行指令碼檔名為$0的變數,第一個接的引數就是$1。除了以上的數字變數外,還有較為特殊的變數可以在script中使用來呼叫這些引數。
· $# :代表後接的引數『個數』,以上表為例這裡顯示為『 4 』;
· [email protected] :代表『 "$1" "$2" "$3" "$4" 』之意,每個變數是獨立的(用雙引號括起來);
· $* :代表『 "$1c$2c$3c$4" 』,其中 c 為分隔字元,預設為空格鍵, 所以本例中代表『 "$1 $2 $3 $4" 』之意。
例:執行一個攜帶引數的script。顯示如下資料:程式名為何?共有幾個引數?若引數小於2則告知使用者引數數量太少。全部的引數內容為何?第一個引數內容為何?第二個引數內容為何?
#!/bin/bash
#program
# program shows the scripts name, parameters
#history
# 20181010 lile first release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/temp
export PATH
echo "this script name is ==>${0}" #顯示文件名
echo "total parameter is ==>$# " #顯示引數數量
[ "$#" -lt 2 ] && echo "the number of parameter is less than 2.stop here." && exit 0
#如果引數數量小於2,告知使用者引數過少,大於而則執行下一步
echo "your total parameter is ==>'[email protected]'" #顯示引數的全部內容
echo "your first parameter is ==>${1}" #顯示引數1
echo "your second parameter is ==>${2}" #顯示引數2hoe
#執行如下
$ sh how_paras.sh x w g
this scripts name is ==>how_paras.sh
total parameter is ==>3
your total parameter is ==>x w g
your first parameter is ==>x
your second parameter is ==>w
<1>shift:造成引數變數號碼偏移
#!/bin/bash
#program
# program shows the effect of shift function
#history
# 20181010 lile first release
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/temp
export PATH
echo "total parameter number is ==>$#"
echo "your whole parameter is ==>'[email protected]'"
shift
echo "total parameter number is ==>$#"
echo "your whole parameter is ==>'[email protected]'"
shift
echo "total parameter number is ==>$#"
echo "your whole parameter is ==>'[email protected]'"
[[email protected] temp]$ source shift_paras.sh 1 2 3 4 5 6 7
total parameter number is ==>7 <==最原始的引數變數情況
your whole parameter is ==>'1 2 3 4 5 6 7'
total parameter number is ==>6 <==第一次偏移,偏移量為1,引數1消失
your whole parameter is ==>'2 3 4 5 6 7'
total parameter number is ==>3 <==第二次偏移。偏移量為3,引數234消失
your whole parameter is ==>'5 6 7'
由上可知,shift具有移動變數的功能,shift後面接數字,即為拿掉幾個變數的意思。