<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 12.3 善用判斷式 在第十章中,我們提到過 [$?](../Text/index.html#returnvar) 這個變量所代表的意義, 此外,也通過 [&& 及 ||](../Text/index.html#redirect_com) 來作為前一個指令執行回傳值對于后一個指令是否要進行的依據。第十章的討論中,如果想要判斷一個目錄是否存在, 當時我們使用的是 ls 這個指令搭配數據流重導向,最后配合 $? 來決定后續的指令進行與否。 但是否有更簡單的方式可以來進行“條件判斷”呢?有的~那就是“ test ”這個指令。 ### 12.3.1 利用 test 指令的測試功能 當我要檢測系統上面某些文件或者是相關的屬性時,利用 test 這個指令來工作真是好用得不得了, 舉例來說,我要檢查 /dmtsai 是否存在時,使用: ``` [dmtsai@study ~]$ test -e /dmtsai ``` 執行結果并不會顯示任何訊息,但最后我們可以通過 $? 或 && 及 || 來展現整個結果呢! 例如我們在將上面的例子改寫成這樣: ``` [dmtsai@study ~]$ test -e /dmtsai && echo "exist" &#124;&#124; echo "Not exist" Not exist &lt;==結果顯示不存在啊! ``` 最終的結果可以告知我們是“exist”還是“Not exist”呢!那我知道 -e 是測試一個“東西”在不在, 如果還想要測試一下該文件名是啥玩意兒時,還有哪些標志可以來判斷的呢?呵呵!有下面這些東西喔! | 測試的標志 | 代表意義 | | --- | --- | | 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 | OK!現在我們就利用 test 來幫我們寫幾個簡單的例子。首先,判斷一下,讓使用者輸入一個文件名,我們判斷: 1. 這個文件是否存在,若不存在則給予一個“Filename does not exist”的訊息,并中斷程序; 2. 若這個文件存在,則判斷他是個文件或目錄,結果輸出“Filename is regular file”或 “Filename is directory” 3. 判斷一下,執行者的身份對這個文件或目錄所擁有的權限,并輸出權限數據! 你可以先自行創作看看,然后再跟下面的結果討論討論。注意利用 test 與 && 還有 || 等標志! ``` [dmtsai@study bin]$ vim file_perm.sh #!/bin/bash # Program: # User input a filename, program will check the flowing: # 1.) exist? 2.) file/directory? 3.) file permissions # History: # 2015/07/16 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH # 1\. 讓使用者輸入文件名,并且判斷使用者是否真的有輸入字串? echo -e "Please input a filename, I will check the filename's type and permission. \n\n" 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 permissions for you are : ${perm}" ``` 如果你執行這個腳本后,他會依據你輸入的文件名來進行檢查喔!先看是否存在,再看為文件或目錄類型,最后判斷權限。 但是你必須要注意的是,由于 root 在很多權限的限制上面都是無效的,所以使用 root 執行這個腳本時, 常常會發現與 ls -l 觀察到的結果并不相同!所以,建議使用一般使用者來執行這個腳本試看看。 ### 12.3.2 利用判斷符號 [ ] 除了我們很喜歡使用的 test 之外,其實,我們還可以利用判斷符號“ [ ] ”(就是中括號啦) 來進行數據的判斷呢! 舉例來說,如果我想要知道 ${HOME} 這個變量是否為空的,可以這樣做: ``` [dmtsai@study ~]$ [ -z "${HOME}" ] ; echo $? ``` 使用中括號必須要特別注意,因為中括號用在很多地方,包括萬用字符與正則表達式等等,所以如果要在 bash 的語法當中使用中括號作為 shell 的判斷式時,必須要注意中括號的兩端需要有空白字符來分隔喔! 假設我空白鍵使用“□”符號來表示,那么,在這些地方你都需要有空白鍵: ``` [ "$HOME" == "$MAIL" ] [□"$HOME"□==□"$MAIL"□] ↑ ↑ ↑ ↑ ``` ![鳥哥的圖示](https://box.kancloud.cn/2016-05-13_5735736501917.gif "鳥哥的圖示") **Tips** 你會發現鳥哥在上面的判斷式當中使用了兩個等號“ == ”。其實在 bash 當中使用一個等號與兩個等號的結果是一樣的! 不過在一般慣用程序的寫法中,一個等號代表“變量的設置”,兩個等號則是代表“邏輯判斷 (是與否之意)”。 由于我們在中括號內重點在于“判斷”而非“設置變量”,因此鳥哥建議您還是使用兩個等號較佳! 上面的例子在說明,兩個字串 ${HOME} 與 ${MAIL} 是否相同的意思,相當于 test ${HOME} == ${MAIL} 的意思啦! 而如果沒有空白分隔,例如 [${HOME}==${MAIL}] 時,我們的 bash 就會顯示錯誤訊息了!這可要很注意啊! 所以說,你最好要注意: * 在中括號 [] 內的每個元件都需要有空白鍵來分隔; * 在中括號內的變量,最好都以雙引號括號起來; * 在中括號內的常數,最好都以單或雙引號括號起來。 為什么要這么麻煩啊?直接舉例來說,假如我設置了 name="VBird Tsai" ,然后這樣判定: ``` [dmtsai@study ~]$ name="VBird Tsai" [dmtsai@study ~]$ [ ${name} == "VBird" ] bash: [: too many arguments ``` 見鬼了!怎么會發生錯誤啊?bash 還跟我說錯誤是由于“太多參數 (arguments)”所致! 為什么呢?因為 ${name} 如果沒有使用雙引號刮起來,那么上面的判定式會變成: > [ VBird Tsai == "VBird" ] 上面肯定不對嘛!因為一個判斷式僅能有兩個數據的比對,上面 VBird 與 Tsai 還有 "VBird" 就有三個數據! 這不是我們要的!我們要的應該是下面這個樣子: > [ "VBird Tsai" == "VBird" ] 這可是差很多的喔!另外,中括號的使用方法與 test 幾乎一模一樣啊~ 只是中括號比較常用在[條件判斷式 if ..... then ..... fi](../Text/index.html#rule) 的情況中就是了。 好,那我們也使用中括號的判斷來做一個小案例好了,案例設置如下: 1. 當執行一個程序的時候,這個程序會讓使用者選擇 Y 或 N , 2. 如果使用者輸入 Y 或 y 時,就顯示“ OK, continue ” 3. 如果使用者輸入 n 或 N 時,就顯示“ Oh, interrupt !” 4. 如果不是 Y/y/N/n 之內的其他字符,就顯示“ I don't know what your choice is ” 利用中括號、 && 與 || 來繼續吧! ``` [dmtsai@study bin]$ vim ans_yn.sh #!/bin/bash # Program: # This program shows the user's choice # History: # 2015/07/16 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH read -p "Please input (Y/N): " yn [ "${yn}" == "Y" -o "${yn}" == "y" ] && echo "OK, continue" && exit 0 [ "${yn}" == "N" -o "${yn}" == "n" ] && echo "Oh, interrupt!" && exit 0 echo "I don't know what your choice is" && exit 0 ``` 由于輸入正確 (Yes) 的方法有大小寫之分,不論輸入大寫 Y 或小寫 y 都是可以的,此時判斷式內就得要有兩個判斷才行! 由于是任何一個成立即可 (大寫或小寫的 y) ,所以這里使用 -o (或) 鏈接兩個判斷喔! 很有趣吧!利用這個字串判別的方法,我們就可以很輕松的將使用者想要進行的工作分門別類呢! 接下來,我們再來談一些其他有的沒有的東西吧! ### 12.3.3 Shell script 的默認變量($0, $1...) 我們知道指令可以帶有選項與參數,例如 ls -la 可以察看包含隱藏文件的所有屬性與權限。那么 shell script 能不能在腳本文件名后面帶有參數呢?很有趣喔!舉例來說,如果你想要重新啟動系統的網絡,可以這樣做: ``` [dmtsai@study ~]$ file /etc/init.d/network /etc/init.d/network: Bourne-Again shell script, ASCII text executable # 使用 file 來查詢后,系統告知這個文件是個 bash 的可執行 script 喔! [dmtsai@study ~]$ /etc/init.d/network restart ``` restart 是重新啟動的意思,上面的指令可以“重新啟動 /etc/init.d/network 這支程序”的意思! 唔!那么如果你在 /etc/init.d/network 后面加上 stop 呢?沒錯!就可以直接關閉該服務了!這么神奇啊? 沒錯啊!如果你要依據程序的執行給予一些變量去進行不同的任務時,本章一開始是使用 [read](../Text/index.html#ex_read) 的功能!但 read 功能的問題是你得要手動由鍵盤輸入一些判斷式。如果通過指令后面接參數, 那么一個指令就能夠處理完畢而不需要手動再次輸入一些變量行為!這樣下達指令會比較簡單方便啦! script 是怎么達成這個功能的呢?其實 script 針對參數已經有設置好一些變量名稱了!對應如下: ``` /path/to/scriptname opt1 opt2 opt3 opt4 $0 $1 $2 $3 $4 ``` 這樣夠清楚了吧?執行的腳本文件名為 $0 這個變量,第一個接的參數就是 $1 啊~ 所以,只要我們在 script 里面善用 $1 的話,就可以很簡單的立即下達某些指令功能了!除了這些數字的變量之外, 我們還有一些較為特殊的變量可以在 script 內使用來調用這些參數喔! * $# :代表后接的參數“個數”,以上表為例這里顯示為“ 4 ”; * $@ :代表“ "$1" "$2" "$3" "$4" ”之意,每個變量是獨立的(用雙引號括起來); * $* :代表“ "$1&lt;u&gt;c&lt;/u&gt;$2&lt;u&gt;c&lt;/u&gt;$3&lt;u&gt;c&lt;/u&gt;$4" ”,其中 &lt;u&gt;c&lt;/u&gt; 為分隔字符,默認為空白鍵, 所以本例中代表“ "$1 $2 $3 $4" ”之意。 那個 $@ 與 $* 基本上還是有所不同啦!不過,一般使用情況下可以直接記憶 $@ 即可! 好了,來做個例子吧~假設我要執行一個可以攜帶參數的 script ,執行該腳本后屏幕會顯示如下的數據: * 程序的文件名為何? * 共有幾個參數? * 若參數的個數小于 2 則告知使用者參數數量太少 * 全部的參數內容為何? * 第一個參數為何? * 第二個參數為何 ``` [dmtsai@study bin]$ vim how_paras.sh #!/bin/bash # Program: # Program shows the script name, parameters... # History: # 2015/07/16 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH echo "The script name is ==&gt; ${0}" echo "Total parameter number is ==&gt; $#" [ "$#" -lt 2 ] && echo "The number of parameter is less than 2\. Stop here." && exit 0 echo "Your whole parameter is ==&gt; '$@'" echo "The 1st parameter ==&gt; ${1}" echo "The 2nd parameter ==&gt; ${2}" ``` 執行結果如下: ``` [dmtsai@study bin]$ sh how_paras.sh theone haha quot The script name is ==&gt; how_paras.sh &lt;==文件名 Total parameter number is ==&gt; 3 &lt;==果然有三個參數 Your whole parameter is ==&gt; 'theone haha quot' &lt;==參數的內容全部 The 1st parameter ==&gt; theone &lt;==第一個參數 The 2nd parameter ==&gt; haha &lt;==第二個參數 ``` * shift:造成參數變量號碼偏移 除此之外,腳本后面所接的變量是否能夠進行偏移 (shift) 呢?什么是偏移啊?我們直接以下面的范例來說明好了, 用范例說明比較好解釋!我們將 how_paras.sh 的內容稍作變化一下,用來顯示每次偏移后參數的變化情況: ``` [dmtsai@study bin]$ vim shift_paras.sh #!/bin/bash # Program: # Program shows the effect of shift function. # History: # 2009/02/17 VBird First release PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH echo "Total parameter number is ==&gt; $#" echo "Your whole parameter is ==&gt; '$@'" shift # 進行第一次“一個變量的 shift ” echo "Total parameter number is ==&gt; $#" echo "Your whole parameter is ==&gt; '$@'" shift 3 # 進行第二次“三個變量的 shift ” echo "Total parameter number is ==&gt; $#" echo "Your whole parameter is ==&gt; '$@'" ``` 這玩意的執行成果如下: ``` [dmtsai@study bin]$ sh shift_paras.sh one two three four five six &lt;==給予六個參數 Total parameter number is ==&gt; 6 &lt;==最原始的參數變量情況 Your whole parameter is ==&gt; 'one two three four five six' Total parameter number is ==&gt; 5 &lt;==第一次偏移,看下面發現第一個 one 不見了 Your whole parameter is ==&gt; 'two three four five six' Total parameter number is ==&gt; 2 &lt;==第二次偏移掉三個,two three four 不見了 Your whole parameter is ==&gt; 'five six' ``` 光看結果你就可以知道啦,那個 shift 會移動變量,而且 shift 后面可以接數字,代表拿掉最前面的幾個參數的意思。 上面的執行結果中,第一次進行 shift 后他的顯示情況是“ one two three four five six”,所以就剩下五個啦!第二次直接拿掉三個,就變成“ two three four five six ”啦! 這樣這個案例可以了解了嗎?理解了 shift 的功能了嗎? 上面這幾個例子都很簡單吧?幾乎都是利用 bash 的相關功能而已~ 不難啦~下面我們就要使用條件判斷式來進行一些分別功能的設置了,好好瞧一瞧先~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看