1. 程式人生 > >鳥哥的Linux私房菜讀書筆記--判斷式

鳥哥的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後面接數字,即為拿掉幾個變數的意思。