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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 10.2 參數替換 參數替換用來處理或擴展變量。 ### `${parameter}` 等同于 `$parameter`,是變量 parameter 的值。在一些特定的環境下,只允許使用不易混淆的 `${parameter}` 形式。 可以用于連接變量與字符串。 ```bash your_id=${USER}-on-${HOSTNAME} echo "$your_id" # echo "Old \$PATH = $PATH" PATH=${PATH}:/opt/bin # 在腳本執行過程中臨時在 $PATH 中加入 /opt/bin。 echo "New \$PATH = $PATH" ``` ### `${parameter-default}, ${parameter:-default}` 在沒有設置變量的情況下使用缺省值。 ```bash var1=1 var2=2 # 沒有設置 var3。 echo ${var1-$var2} # 1 echo ${var3-$var2} # 2 # ^ 注意前面的 $ 前綴。 echo ${username-`whoami`} # 如果變量 $username 沒有被設置,輸出 `whoami` 的結果。 ``` > ![note](http://tldp.org/LDP/abs/images/note.gif) `${parameter-default}` 與 `${parameter:-default}` 的作用幾乎相同,唯一不同的情況就是當變量 parameter 已經被聲明但值為空時。 ```bash #!/bin/bash # param-sub.sh # 無論變量的值是否為空,其是否已被聲明決定了缺省設置的觸發。 username0= echo "username0 has been declared, but is set to null." echo "username0 = ${username0-`whoami`}" # 將不會輸出 `whoami` 的結果。 echo echo username1 has not been declared. echo "username1 = ${username1-`whoami`}" # 將會輸出 `whoami` 的結果。 username2= echo "username2 has been declared, but is set to null." echo "username2 = ${username2:-`whoami`}" # ^ # 因為這里是 :- 而不是 -,所以將會輸出 `whoami` 的結果。 # 與上面的 username0 比較。 # # 再來一次: variable= # 變量已被聲明,但其值為空。 echo "${varibale-0}" # 沒有輸出。 echo "${variable:-1}" # 1 # ^ unser variable echo "${variable-2}" # 2 echo "${variable:-3}" # 3 exit 0 ``` 當傳入的命令行參數的數量不足時,可以使用這種缺省參數結構。 ```bash DEFAULT_FILENAME=generic.data filename=${1:-$DEFAULT_FILENAME} # 如果沒有其他特殊情況,下面的代碼塊將會操作文件 "generic.data"。 # 代碼塊開始 # ... # ... # ... # 代碼塊結束 # 摘自樣例 "hanoi2.bash": DISKS=${1:-E_NOPARAM} # 必須指定碟子的個數。 # 將 $DISKS 設置為傳入的第一個命令行參數, #+ 如果沒有傳入第一個參數,則設置為 $E_NOPARAM。 ``` 可以查看 [樣例 3-4](http://tldp.org/LDP/abs/html/special-chars.html#EX58),[樣例 31-2](http://tldp.org/LDP/abs/html/zeros.html#EX73) 和 [樣例 A-6](http://tldp.org/LDP/abs/html/contributed-scripts.html#COLLATZ)。 可以同 [使用與鏈設置缺省命令行參數](http://tldp.org/LDP/abs/html/list-cons.html#ANDDEFAULT) 做比較。 ### `${parameter=default}, ${parameter:=default}` 在沒有設置變量的情況下,將其設置為缺省值。 兩種形式的作用幾乎相同,唯一不同的情況與上面類似,就是當變量 parameter 已經被聲明但值為空時。[^1] ```bash echo ${var=abc} # abc echo ${vat=xyz} # abc # $var 已經在第一條語句中被賦值為 abc,因此第二條語句將不會改變它的值。 ``` ### `${parameter+alt_value}, ${parameter:+alt_value}` 如果變量已被設置,使用 alt_value,否則使用空值。 兩種形式的作用幾乎相同,唯一不同的情況就是當變量 parameter 已經被聲明但值為空時,看下面的例子。 ```bash echo "###### \${parameter+alt_value} ########" echo a=${param1+xyz} echo "a = $a" # a = param2= a=${param2+xyz} echo "a = $a" # a = xyz param3=123 a=${param3+xyz} echo "a = $a" # a = xyz echo echo "###### \${parameter:+alt_value} ########" echo a=${param4:+xyz} echo "a = $a" # a = param5= a=${param5:+xyz} echo "a = $a" # a = # 不同于 a=${param5+xyz} param6=123 a=${param6:+xyz} echo "a = $a" # a = xyz ``` ### `${parameter?err_msg}, ${parameter:?err_msg}` 如果變量已被設置,那么使用原值,否則輸出 err_msg 并且終止腳本,返回 [錯誤碼](http://tldp.org/LDP/abs/html/exit-status.html#EXITSTATUSREF) 1。 兩種形式的作用幾乎相同,唯一不同的情況與上面類似,就是當變量 parameter 已經被聲明但值為空時。 樣例 10-7. 如何使用變量替換和錯誤信息 ```bash #!/bin/bash # 檢查系統環境變量。 # 這是一種良好的預防性維護措施。 # 如果控制臺用戶的名稱 $USER 沒有被設置,那么主機將不能夠識別用戶。 : ${HOSTNAME?} ${USER?} ${HOME?} ${MAIL?} echo echo "Name of the machine is $HOSTNAME." echo "You are $USER." echo "Your home directory is $HOME." echo "Your mail INBOX is located in $MAIL." echo echo "If you are reading this message," echo "critcial environmental variables have been set." echo echo # ------------------------------------------------------ # ${variablename?} 結構統一可以檢查腳本中的變量是否被設置。 ThisVariable=Value-of-ThisVariable # 順帶一提,這個字符串的值可以被設置成名稱中不可以使用的禁用字符。 : ${ThisVariable?} echo "Value of ThisVariable is $ThisVariable." echo; echo : ${ZZXy23AB?"ZZXy23AB has not been set."} # 因為 ZZXy23AB 沒有被設置,所以腳本會終止同時顯示錯誤消息。 # 你可以指定錯誤消息。 # : ${variablename?"ERROR MESSAGE"} # 與這些結果相同: dummy_variable=${ZZXy23AB?} # dummy_variable=${ZZXy23AB?"ZZXy23AB has not been set."} # # echo ${ZZXy23AB?} >/dev/null # 將上面這些檢查變量是否被設置的方法同 "set -u" 作比較。 echo "You will not see this message, because script already terminated." HERE=0 exit $HERE # 將不會從這里退出。 # 事實上,這個腳本將會返回退出碼(echo $?)1。 ``` 樣例 10-8. 參數替換與 "usage" 消息 ```bash #!/bin/bash # usage-message.sh : ${1?"Usage: $0 ARGUMENT"} # 如果命令行參數缺失,腳本將會在這里結束,并且返回下面的錯誤信息。 # usage-message.sh: 1: Usage: usage-message.sh ARGUMENT echo "These two lines echo only if command-line parameter given." echo "command-line parameter = \"$1\"" exit 0 # 僅當命令行參數存在是才會從這里退出。 # 在傳入和未傳入命令行參數的情況下查看退出狀態。 # 如果傳入了命令行參數,那么 "$?" 的結果是0。 # 如果沒有,那么 "$?" 的結果是1。 ``` 參數替換用來處理或擴展變量。下面的表達式是對 `expr` 處理字符串的操作的補足(查看樣例 16-9)。這些特殊的表達式通常養來解析文件的路徑名。 ### 變量長度 / 刪除子串 #### `${#var}` 字符串的長度(`$var` 中字符的個數)。對任意 [數組](http://tldp.org/LDP/abs/html/arrays.html#ARRAYREF) array,`${#array}` 返回數組中第一個元素的長度。 > ![note](http://tldp.org/LDP/abs/images/note.gif) 以下情況例外: > > * `${#*}` 和 `${#@}` 返回位置參數的個數。 > * 任意數組 array,`${#array[*]}` 和 `${#array[@]}` 返回數組中元素的個數。 樣例 10-9. 變量長度 ```bash #!/bin/bash # length.sh E_NO_ARGS=65 if [ $# -eq 0 ] # 腳本必須傳入參數。 then echo "Please invoke this script with one or more command-line arguments." exit $E_NO_ARGS fi var01=abcdEFGH28ij echo "var01 = ${var01}" echo "Length of var01 = ${#var01}" # 現在我們嘗試加入空格。 var02="abcd EFGH28ij" echo "var02 = ${var02}" echo "Length of var02 = ${#var02}" echo "Number of command-line arguments passed to script = ${#@}" echo "Number of command-line arguments passed to script = ${#*}" exit 0 ``` #### `${var#Pattern}, ${var##Pattern}` `${var#Pattern}` 刪除 `$var` 前綴部分匹配到的最短長度的 `$Pattern`。 `${var##Pattern}` 刪除 `$var` 前綴部分匹配到的最長長度的 `$Pattern`。 摘自 [樣例 A-7](http://tldp.org/LDP/abs/html/contributed-scripts.html#DAYSBETWEEN) 的例子: ```bash # 函數摘自樣例 "day-between.sh"。 # 刪除傳入的參數中的前綴0。 strip_leading_zero () # 刪除傳入參數中可能存在的 { #+ 前綴0。 return=${1#0} # "1" 代表 "$1",即傳入的參數。 } # 從 "$1" 中刪除 "0"。 ``` 下面是由 Manfred Schwarb 提供的上述函數的改進版本: ```bash strip_leading_zero2 () # 刪除前綴0, { # 否則 Bash 會將其解釋為8進制數。 shopt -s extglob # 啟用擴展通配特性。 local val=${1##+(0)} # 使用本地變量,匹配前綴中所有的0。 shopt -u extglob # 禁用擴展通配特性。 _strip_leading_zero2=${var:-0} # 如果輸入的為0,那么返回 0 而不是 ""。 ``` 另外一個樣例: ```bash echo `basename $PWD` # 當前工作目錄的目錄名。 echo "${PWD##*/}" # 當前工作目錄的目錄名。 echo echo `basename $0` # 腳本名。 echo $0 # 腳本名。 echo "${0##*/}" # 腳本名。 echo filename=test.data echo "${filename##*.}" # data # 文件擴展名。 ``` #### `${var%Pattern}, ${var%%Pattern}` `${var%Pattern}` 刪除 `$var` 后綴部分匹配到的最短長度的 `$Pattern`。 `${var%%Pattern}` 刪除 `$var` 后綴部分匹配到的最長長度的 `$Pattern`。 在 Bash 的 [第二個版本](http://tldp.org/LDP/abs/html/bashver2.html#BASH2REF) 中增加了一些額外的選擇。 樣例 10-10. 參數替換中的模式匹配 ```bash #!/bin/bash # patt-matching.sh # 使用 # ## % %% 參數替換操作符進行模式匹配 var1=abcd12345abc6789 pattern1=a*c # 通配符 * 可以匹配 a 與 c 之間的任意字符 echo echo "var1 = $var1" # abcd12345abc6789 echo "var1 = ${var1}" # abcd12345abc6789 # (另一種形式) echo "Number of characters in ${var1} = ${#var1}" echo echo "pattern1 = $pattern1" # a*c (匹配 'a' 與 'c' 之間的一切) echo "--------------" echo '${var1#$pattern1} =' "${var1#$pattern1}" # d12345abc6789 # 匹配到首部最短的3個字符 abcd12345abc6789 # ^ |-| echo '${var1##$pattern1} =' "${var1##$pattern1}" # 6789 # 匹配到首部最長的12個字符 abcd12345abc6789 # ^ |----------| echo; echo; echo pattern2=b*9 # 匹配 'b' 與 '9' 之間的任意字符 echo "var1 = $var1" # 仍舊是 abcd12345abc6789 echo echo "pattern2 = $pattern2" echo "--------------" echo '${var1%pattern2} =' "${var1%$pattern2}" # abcd12345a # 匹配到尾部最短的6個字符 abcd12345abc6789 # ^ |----| echo '${var1%%pattern2} =' "${var1%%$pattern2}" # a # 匹配到尾部最長的12個字符 abcd12345abc6789 # ^ |-------------| # 牢記 # 與 ## 是從字符串左側開始, # % 與 %% 是從右側開始。 echo exit 0 ``` 樣例 10-11. 更改文件擴展名: ```bash #!/bin/bash # rfe.sh: 更改文件擴展名。 # # rfe old_extension new_extension # # 如: # 將當前目錄下所有 *.gif 文件重命名為 *.jpg, # rfe gif jpg E_BADARGS=65 case $# in 0|1) # 豎線 | 在這里表示邏輯或關系。 echo "Usage: `basename $0` old_file_suffix new_file_suffix" exit $E_BADARGS # 如果只有0個或1個參數,那么退出腳本。 ;; esac for filename in *.$1 # 遍歷以第一個參數作為后綴名的文件列表。 do mv $filename ${filename%$1}$2 # 刪除文件后綴名,增加第二個參數作為后綴名。 done exit 0 ``` ### 變量擴展 / 替換子串 下面這些結構采用自 ksh。 #### `${var:pos}` 擴展為從偏移量 pos 處截取的變量 var。 #### `${var:pos:len}` 擴展為從偏移量 pos 處截取變量 var 最大長度為 len 的字符串。 #### `${var/Pattern/Replacement}` 替換 var 中第一個匹配到的 Pattern 為 Replacement。 如果 Replacement 被省略,那么匹配到的第一個 Pattern 將被替換為空,即刪除。 #### `${var//Pattern/Replacement}` 全局替換。替換 var 中所有匹配到的 Pattern 為 Replacement。 跟上面一樣,如果 Replacement 被省略,那么匹配到的所有 Pattern 將被替換為空,即刪除。 樣例 10-12. 使用模式匹配解析任意字符串 ```bash #!/bin/bash var1=abcd-1234-defg echo "var1 = $var1" t=${var1#*-*} echo "var1 (with everything, up to and including first - stripped out) = $t" # t=${var1#*-} 效果相同, #+ 因為 # 只匹配最短的字符串, #+ 并且 * 可以任意匹配,其中也包括空字符串。 # (感謝 Stephane Chazelas 指出這一點。) t=${var##*-*} echo "If var1 contains a \"-\", returns empty string... var1 = $t" t=${var1%*-*} echo "var1 (with everything from the last - on stripped out) = $t" echo # ------------------------------------------- path_name=/home/bozo/ideas/thoughts/for.today # ------------------------------------------- echo "path_name = $path_name" t=${path_name##/*/} echo "path_name, stripped of prefixes = $t" # 在這里與 t=`basename $path_name` 效果相同。 # t=${path_name%/}; t=${t##*/} 是更加通用的方法, #+ 但有時仍舊也會出現問題。 # 如果 $path_name 以換行結束,那么 `basename $path_name` 將會失效, #+ 但是上面這種表達式卻可以。 # (感謝 S.C.) t=${path_name%/*.*} # 同 t=`dirname $path_name` 效果相同。 echo "path_name, stripped of suffixes = $t" # 在一些情況下會失效,比如 "../", "/foo////", # "foo/", "/"。 # 在刪除后綴時,尤其是當文件名沒有后綴,目錄名卻有后綴時, #+ 事情會變的非常復雜。 # (感謝 S.C.) echo t=${path_name:11} echo "$path_name, with first 11 chars stripped off = $t" t=${path_name:11:5} echo "$path_name, with first 11 chars stripped off, length 5 = $t" echo t=${path_name/bozo/clown} echo "$path_name with \"bozo\" replaced by \"clown\" = $t" t=${path_name/today/} echo "$path_name with \"today\" deleted = $t" t=${path_name//o/O} echo "$path_name with all o's capitalized = $t" t=${path_name//o/} echo "$path_name with all o's deleted = $t" exit 0 ``` #### `${var/#Pattern/Replacement}` 替換 var 前綴部分匹配到的 Pattern 為 Replacement。 #### `${var/%Pattern/Replacement}` 替換 var 后綴部分匹配到的 Pattern 為 Replacement。 樣例 10-13. 在字符串首部或尾部進行模式匹配 ```bash #!/bin/bash # var-match.sh: # 演示在字符串首部或尾部進行模式替換。 v0=abc1234zip1234abc # 初始值。 echo "v0 = $v0" # abc1234zip1234abc echo # 在字符串首部進行匹配 v1=${v0/#abc/ABCDEF} # abc1234zip123abc # |-| echo "v1 = $v1" # ABCDEF1234zip1234abc # |----| # 在字符串尾部進行匹配 v2=${v0/%abc/ABCDEF} # abc1234zip123abc # |-| echo "v2 = $v2" # abc1234zip1234ABCDEF # |----| echo # -------------------------------------------- # 必須在字符串的最開始或者最末尾的地方進行匹配, #+ 否則將不會發生替換。 # -------------------------------------------- v3=${v0/#123/000} # 雖然匹配到了,但是不在最開始的地方。 echo "v3 = $v3" # abc1234zip1234abc # 沒有替換。 v4=${v0/%123/000} # 雖然匹配到了,但是不在最末尾的地方。 echo "v4 = $v4" # abc1234zip1234abc # 沒有替換。 exit 0 ``` #### `${!varprefix*}, ${!varprefix@}` 匹配先前聲明過所有以 varprefix 作為變量名前綴的變量。 ```bash # 這是帶 * 或 @ 的間接引用的一種變換形式。 # 在 Bash 2.04 版本中加入了這個特性。 xyz23=whatever xyz23= a=${!xyz*} # 擴展為聲明變量中以 "xyz" # ^ ^ ^ + 開頭變量名。 echo "a = $a" # a = xyz23 xyz24 a=${!xyz@} # 同上。 echo "a = $a" # a = xyz23 xyz24 echo "---" abc23=something_else b=${!abc*} echo "b = $b" # b = abc23 c=${!b} # 這是我們熟悉的間接引用的形式。 echo $c # something_else ``` [^1]: 如果在非交互的腳本中,`$parameter` 為空,那么程序將會終止,并且返回 [錯誤碼 127](http://tldp.org/LDP/abs/html/exitcodes.html#EXITCODESREF)(意為“找不到命令”)。
                  <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>

                              哎呀哎呀视频在线观看