<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ~~~ if commands; then commands fi if commands; then commands else commands fi if commands; then commands elif commands; then commands... else commands fi ~~~ `if`和`then`寫在同一行時,需要命令分隔符`;`分隔 單行寫法 ~~~ if true; then echo 'hello world'; fi ~~~ `if`結構的判斷條件,一般使用`test`命令,有三種形式。 ~~~ # 寫法一 test expression # 寫法二 [ expression ] # 寫法三 [[ expression ]] ~~~ 上面三種形式是等價的,但是第三種形式還支持正則判斷,前兩種不支持。 上面的`expression`是一個表達式。這個表達式為真,`test`命令執行成功(返回值為`0`);表達式為偽,`test`命令執行失敗(返回值為`1`)。注意,第二種和第三種寫法,`[`和`]`與內部的表達式之間必須有空格。 判斷`/etc/hosts`文件是否存在,這兩種寫法是等價的 ~~~ $ test -f /etc/hosts $ echo $? 0 $ [ -f /etc/hosts ] $ echo $? 0 ~~~ 下面把`test`命令的三種形式,用在`if`結構中,判斷一個文件是否存在。 ~~~ # 寫法一 if test -e /tmp/foo.txt ; then echo "Found foo.txt" fi # 寫法二 if [ -e /tmp/foo.txt ] ; then echo "Found foo.txt" fi # 寫法三 if [[ -e /tmp/foo.txt ]] ; then echo "Found foo.txt" fi ~~~ ## 判斷表達式 `if`關鍵字后面,跟的是一個命令。這個命令可以是`test`命令,也可以是其他命令。命令的返回值為`0`表示判斷成立,否則表示不成立。因為這些命令主要是為了得到返回值,所以可以視為表達式。 常用的判斷表達式有下面這些。 ### 文件判斷 以下表達式用來判斷文件狀態。 * `[ -a file ]`:如果 file 存在,則為`true`。 * `[ -b file ]`:如果 file 存在并且是一個塊(設備)文件,則為`true`。 * `[ -c file ]`:如果 file 存在并且是一個字符(設備)文件,則為`true`。 * `[ -d file ]`:如果 file 存在并且是一個目錄,則為`true`。 * `[ -e file ]`:如果 file 存在,則為`true`。 * `[ -f file ]`:如果 file 存在并且是一個普通文件,則為`true`。 * `[ -g file ]`:如果 file 存在并且設置了組 ID,則為`true`。 * `[ -G file ]`:如果 file 存在并且屬于有效的組 ID,則為`true`。 * `[ -h file ]`:如果 file 存在并且是符號鏈接,則為`true`。 * `[ -k file ]`:如果 file 存在并且設置了它的“sticky bit”,則為`true`。 * `[ -L file ]`:如果 file 存在并且是一個符號鏈接,則為`true`。 * `[ -N file ]`:如果 file 存在并且自上次讀取后已被修改,則為`true`。 * `[ -O file ]`:如果 file 存在并且屬于有效的用戶 ID,則為`true`。 * `[ -p file ]`:如果 file 存在并且是一個命名管道,則為`true`。 * `[ -r file ]`:如果 file 存在并且可讀(當前用戶有可讀權限),則為`true`。 * `[ -s file ]`:如果 file 存在且其長度大于零,則為`true`。 * `[ -S file ]`:如果 file 存在且是一個網絡 socket,則為`true`。 * `[ -t fd ]`:如果 fd 是一個文件描述符,并且重定向到終端,則為`true`。 這可以用來判斷是否重定向了標準輸入/輸出/錯誤。 * `[ -u file ]`:如果 file 存在并且設置了 setuid 位,則為`true`。 * `[ -w file ]`:如果 file 存在并且可寫(當前用戶擁有可寫權限),則為`true`。 * `[ -x file ]`:如果 file 存在并且可執行(有效用戶有執行/搜索權限),則為`true`。 * `[ file1 -nt file2 ]`:如果 FILE1 比 FILE2 的更新時間最近,或者 FILE1 存在而 FILE2 不存在,則為`true`。 * `[ file1 -ot file2 ]`:如果 FILE1 比 FILE2 的更新時間更舊,或者 FILE2 存在而 FILE1 不存在,則為`true`。 * `[ FILE1 -ef FILE2 ]`:如果 FILE1 和 FILE2 引用相同的設備和 inode 編號,則為`true`。 下面是一個示例。 ~~~ #!/bin/bash FILE=~/.bashrc if [ -e "$FILE" ]; then if [ -f "$FILE" ]; then echo "$FILE is a regular file." fi if [ -d "$FILE" ]; then echo "$FILE is a directory." fi if [ -r "$FILE" ]; then echo "$FILE is readable." fi if [ -w "$FILE" ]; then echo "$FILE is writable." fi if [ -x "$FILE" ]; then echo "$FILE is executable/searchable." fi else echo "$FILE does not exist" exit 1 fi ~~~ 上面代碼中,`$FILE`要放在雙引號之中。這樣可以防止`$FILE`為空,因為這時`[ -e ]`會判斷為真。而放在雙引號之中,返回的就總是一個空字符串,`[ -e "" ]`會判斷為偽。 ### 字符串判斷 以下表達式用來判斷字符串。 * `[ string ]`:如果`string`不為空(長度大于0),則判斷為真。 * `[ -n string ]`:如果字符串`string`的長度大于零,則判斷為真。 * `[ -z string ]`:如果字符串`string`的長度為零,則判斷為真。 * `[ string1 = string2 ]`:如果`string1`和`string2`相同,則判斷為真。 * `[ string1 == string2 ]`等同于`[ string1 = string2 ]`。 * `[ string1 != string2 ]`:如果`string1`和`string2`不相同,則判斷為真。 * `[ string1 '>' string2 ]`:如果按照字典順序`string1`排列在`string2`之后,則判斷為真。 * `[ string1 '<' string2 ]`:如果按照字典順序`string1`排列在`string2`之前,則判斷為真。 注意,`test`命令內部的`>`和`<`,必須用引號引起來(或者是用反斜杠轉義)。否則,它們會被 shell 解釋為重定向操作符。 下面是一個示例。 ~~~ #!/bin/bash ANSWER=maybe if [ -z "$ANSWER" ]; then echo "There is no answer." >&2 exit 1 fi if [ "$ANSWER" = "yes" ]; then echo "The answer is YES." elif [ "$ANSWER" = "no" ]; then echo "The answer is NO." elif [ "$ANSWER" = "maybe" ]; then echo "The answer is MAYBE." else echo "The answer is UNKNOWN." fi ~~~ 上面代碼中,首先確定`$ANSWER`字符串是否為空。如果為空,就終止腳本,并把退出狀態設為`1`。注意,這里的`echo`命令把錯誤信息`There is no answer.`重定向到標準錯誤,這是處理錯誤信息的常用方法。如果`$ANSWER`字符串不為空,就判斷它的值是否等于`yes`、`no`或者`maybe`。 注意,字符串判斷時,變量要放在雙引號之中,比如`[ -n "$COUNT" ]`,否則變量替換成字符串以后,`test`命令可能會報錯,提示參數過多。另外,如果不放在雙引號之中,變量為空時,命令會變成`[ -n ]`,這時會判斷為真。如果放在雙引號之中,`[ -n "" ]`就判斷為偽。 ### 整數判斷 下面的表達式用于判斷整數。 * `[ integer1 -eq integer2 ]`:如果`integer1`等于`integer2`,則為`true`。 * `[ integer1 -ne integer2 ]`:如果`integer1`不等于`integer2`,則為`true`。 * `[ integer1 -le integer2 ]`:如果`integer1`小于或等于`integer2`,則為`true`。 * `[ integer1 -lt integer2 ]`:如果`integer1`小于`integer2`,則為`true`。 * `[ integer1 -ge integer2 ]`:如果`integer1`大于或等于`integer2`,則為`true`。 * `[ integer1 -gt integer2 ]`:如果`integer1`大于`integer2`,則為`true`。 下面是一個用法的例子。 ~~~ #!/bin/bash INT=-5 if [ -z "$INT" ]; then echo "INT is empty." >&2 exit 1 fi if [ $INT -eq 0 ]; then echo "INT is zero." else if [ $INT -lt 0 ]; then echo "INT is negative." else echo "INT is positive." fi if [ $((INT % 2)) -eq 0 ]; then echo "INT is even." else echo "INT is odd." fi fi ~~~ 上面例子中,先判斷變量`$INT`是否為空,然后判斷是否為`0`,接著判斷正負,最后通過求余數判斷奇偶。 ### 正則判斷 `[[ expression ]]`這種判斷形式,支持正則表達式。 ~~~ [[ string1 =~ regex ]] ~~~ 上面的語法中,`regex`是一個正則表示式,`=~`是正則比較運算符。 下面是一個例子。 ~~~ #!/bin/bash INT=-5 if [[ "$INT" =~ ^-?[0-9]+$ ]]; then echo "INT is an integer." exit 0 else echo "INT is not an integer." >&2 exit 1 fi ~~~ 上面代碼中,先判斷變量`INT`的字符串形式,是否滿足`^-?[0-9]+$`的正則模式,如果滿足就表明它是一個整數。 ### test 判斷的邏輯運算 通過邏輯運算,可以把多個`test`判斷表達式結合起來,創造更復雜的判斷。三種邏輯運算`AND`,`OR`,和`NOT`,都有自己的專用符號。 * `AND`運算:符號`&&`,也可使用參數`-a`。 * `OR`運算:符號`||`,也可使用參數`-o`。 * `NOT`運算:符號`!`。 下面是一個`AND`的例子,判斷整數是否在某個范圍之內。 ~~~ #!/bin/bash MIN_VAL=1 MAX_VAL=100 INT=50 if [[ "$INT" =~ ^-?[0-9]+$ ]]; then if [[ $INT -ge $MIN_VAL && $INT -le $MAX_VAL ]]; then echo "$INT is within $MIN_VAL to $MAX_VAL." else echo "$INT is out of range." fi else echo "INT is not an integer." >&2 exit 1 fi ~~~ 上面例子中,`&&`用來連接兩個判斷條件:大于等于`$MIN_VAL`,并且小于等于`$MAX_VAL`。 使用否定操作符`!`時,最好用圓括號確定轉義的范圍。 ~~~ if [ ! \( $INT -ge $MIN_VAL -a $INT -le $MAX_VAL \) ]; then echo "$INT is outside $MIN_VAL to $MAX_VAL." else echo "$INT is in range." fi ~~~ 上面例子中,`test`命令內部使用的圓括號,必須使用引號或者轉義,否則會被 Bash 解釋。 ### 算術判斷 Bash 還提供了`((...))`作為算術條件,進行算術運算的判斷。 ~~~ if ((3 > 2)); then echo "true" fi ~~~ 上面代碼執行后,會打印出`true`。 注意,算術判斷不需要使用`test`命令,而是直接使用`((...))`結構。這個結構的返回值,決定了判斷的真偽。 如果算術計算的結果是非零值,則表示判斷成立。這一點跟命令的返回值正好相反,需要小心。 ~~~ $ if ((1)); then echo "It is true."; fi It is true. $ if ((0)); then echo "It is true."; else echo "it is false."; fi It is false. ~~~ 上面例子中,`((1))`表示判斷成立,`((0))`表示判斷不成立。 算術條件`((...))`也可以用于變量賦值。 ~~~ $ if (( foo = 5 ));then echo "foo is $foo"; fi foo is 5 ~~~ 上面例子中,`(( foo = 5 ))`完成了兩件事情。首先把`5`賦值給變量`foo`,然后根據返回值`5`,判斷條件為真。 注意,賦值語句返回等號右邊的值,如果返回的是`0`,則判斷為假。 ~~~ $ if (( foo = 0 ));then echo "It is true.";else echo "It is false."; fi It is false. ~~~ 下面是用算術條件改寫的數值判斷腳本。 ~~~ #!/bin/bash INT=-5 if [[ "$INT" =~ ^-?[0-9]+$ ]]; then if ((INT == 0)); then echo "INT is zero." else if ((INT < 0)); then echo "INT is negative." else echo "INT is positive." fi if (( ((INT % 2)) == 0)); then echo "INT is even." else echo "INT is odd." fi fi else echo "INT is not an integer." >&2 exit 1 fi ~~~ 只要是算術表達式,都能用于`((...))`語法,詳見《Bash 的算術運算》一章。 ### 普通命令的邏輯運算 如果`if`結構使用的不是`test`命令,而是普通命令,比如上一節的`((...))`算術運算,或者`test`命令與普通命令混用,那么可以使用 Bash 的命令控制操作符`&&`(AND)和`||`(OR),進行多個命令的邏輯運算。 ~~~ $ command1 && command2 $ command1 || command2 ~~~ 對于`&&`操作符,先執行`command1`,只有`command1`執行成功后, 才會執行`command2`。對于`||`操作符,先執行`command1`,只有`command1`執行失敗后, 才會執行`command2`。 ~~~ $ mkdir temp && cd temp ~~~ 上面的命令會創建一個名為`temp`的目錄,執行成功后,才會執行第二個命令,進入這個目錄。 ~~~ $ [ -d temp ] || mkdir temp ~~~ 上面的命令會測試目錄`temp`是否存在,如果不存在,就會執行第二個命令,創建這個目錄。這種寫法非常有助于在腳本中處理錯誤。 ~~~ [ ! -d temp ] && exit 1 ~~~ 上面的命令中,如果`temp`子目錄不存在,腳本會終止,并且返回值為`1`。 下面就是`if`與`&&`結合使用的寫法。 ~~~ if [ condition ] && [ condition ]; then command fi ~~~ 下面是一個示例。 ~~~ #! /bin/bash filename=$1 word1=$2 word2=$3 if grep $word1 $filename && grep $word2 $filename then echo "$word1 and $word2 are both in $filename." fi ~~~ 上面的例子只有在指定文件里面,同時存在搜索詞`word1`和`word2`,就會執行`if`的命令部分。 下面的示例演示如何將一個`&&`判斷表達式,改寫成對應的`if`結構。 ~~~ [[ -d "$dir_name" ]] && cd "$dir_name" && rm * # 等同于 if [[ ! -d "$dir_name" ]]; then echo "No such directory: '$dir_name'" >&2 exit 1 fi if ! cd "$dir_name"; then echo "Cannot cd to '$dir_name'" >&2 exit 1 fi if ! rm *; then echo "File deletion failed. Check results" >&2 exit 1 fi ~~~ ## case 結構 `case`結構用于多值判斷,可以為每個值指定對應的命令,跟包含多個`elif`的`if`結構等價,但是語義更好。它的語法如下。 ~~~ case expression in pattern ) commands ;; pattern ) commands ;; ... esac ~~~ 上面代碼中,`expression`是一個表達式,`pattern`是表達式的值或者一個模式,可以有多條,用來匹配多個值,每條以兩個分號(`;`)結尾。 ~~~ #!/bin/bash echo -n "輸入一個1到3之間的數字(包含兩端)> " read character case $character in 1 ) echo 1 ;; 2 ) echo 2 ;; 3 ) echo 3 ;; * ) echo 輸入不符合要求 esac ~~~ 上面例子中,最后一條匹配語句的模式是`*`,這個通配符可以匹配其他字符和沒有輸入字符的情況,類似`if`的`else`部分。 下面是另一個例子。 ~~~ #!/bin/bash OS=$(uname -s) case "$OS" in FreeBSD) echo "This is FreeBSD" ;; Darwin) echo "This is Mac OSX" ;; AIX) echo "This is AIX" ;; Minix) echo "This is Minix" ;; Linux) echo "This is Linux" ;; *) echo "Failed to identify this OS" ;; esac ~~~ 上面的例子判斷當前是什么操作系統。 `case`的匹配模式可以使用各種通配符,下面是一些例子。 * `a)`:匹配`a`。 * `a|b)`:匹配`a`或`b`。 * `[[:alpha:]])`:匹配單個字母。 * `???)`:匹配3個字符的單詞。 * `*.txt)`:匹配`.txt`結尾。 * `*)`:匹配任意輸入,通過作為`case`結構的最后一個模式。 ~~~ #!/bin/bash echo -n "輸入一個字母或數字 > " read character case $character in [[:lower:]] | [[:upper:]] ) echo "輸入了字母 $character" ;; [0-9] ) echo "輸入了數字 $character" ;; * ) echo "輸入不符合要求" esac ~~~ 上面例子中,使用通配符`[[:lower:]] | [[:upper:]]`匹配字母,`[0-9]`匹配數字。 Bash 4.0之前,`case`結構只能匹配一個條件,然后就會退出`case`結構。Bash 4.0之后,允許匹配多個條件,這時可以用`;;&`終止每個條件塊。 ~~~ #!/bin/bash # test.sh read -n 1 -p "Type a character > " echo case $REPLY in [[:upper:]]) echo "'$REPLY' is upper case." ;;& [[:lower:]]) echo "'$REPLY' is lower case." ;;& [[:alpha:]]) echo "'$REPLY' is alphabetic." ;;& [[:digit:]]) echo "'$REPLY' is a digit." ;;& [[:graph:]]) echo "'$REPLY' is a visible character." ;;& [[:punct:]]) echo "'$REPLY' is a punctuation symbol." ;;& [[:space:]]) echo "'$REPLY' is a whitespace character." ;;& [[:xdigit:]]) echo "'$REPLY' is a hexadecimal digit." ;;& esac ~~~ 執行上面的腳本,會得到下面的結果。 ~~~ $ test.sh Type a character > a 'a' is lower case. 'a' is alphabetic. 'a' is a visible character. 'a' is a hexadecimal digit. ~~~ 可以看到條件語句結尾添加了`;;&`以后,在匹配一個條件之后,并沒有退出`case`結構,而是繼續判斷下一個條件。
                  <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>

                              哎呀哎呀视频在线观看