<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智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 第十二章 命令替換 命令替換重新指定一個[^1]或多個命令的輸出。其實就是將命令的輸出導到另外一個地方[^2]。 命令替換的通常形式是(`` `...` ``),即用反引號引用命令。 ```bash script_name=`basename $0` echo "The name of this script is $scirpt_name." ``` 命令的輸出可以作為另一個命令的參數,也可以賦值給一個變量。甚至在 [`for`](http://tldp.org/LDP/abs/html/loops1.html#FORLOOPREF1) 循環中可以用輸出產生參數表。 ```bash rm `cat filename` # "filename" 中包含了一系列需要被刪除的文件名。 # # S.C. 指出這樣寫可能會導致出現 "arg list too long" 的錯誤。 # 更好的寫法應該是 xargs rm -- < filename # ( -- 可以在 "filename" 文件名以 "-" 為開頭時仍舊正常執行 ) textfile_listing=`ls *.txt` # 變量中包含了當前工作目錄下所有的名為 *.txt 的文件。 echo $textfile_listing textfile_listing2=$(ls *.txt) # 命令替換的另一種形式。 echo $textfile_listing2 # 結果相同。 # 這樣將一系列文件名賦值給一個單一字符串可能會出現換行。 # # 而更加安全的方式是將這一系列文件存入數組。 # shopt -s nullglob # 設置后,如果沒有匹配到文件,那么變量會被賦值為空。 # textfile_listing=( *.txt ) # # 感謝 S.C. ``` > ![note](http://tldp.org/LDP/abs/images/note.gif) 命令替換本質上是調用了一個 [子進程](http://tldp.org/LDP/abs/html/subshells.html#SUBSHELLSREF) 來執行。 > ![caution](http://tldp.org/LDP/abs/images/caution.gif) 命令替換有可能會出現 [字符分割](http://tldp.org/LDP/abs/html/quotingvar.html#WSPLITREF) 的情況。 > ```bash > COMMAND `echo a b` # 2個參數:a和b > > COMMAND "`echo a b`" # 1個參數:"a b" > > COMMAND `echo` # 沒有參數 > > COMMAND "`echo`" # 一個空參數 > > > # 感謝 S.C. > ``` > 但即使不存在字符分割的情況,使用命令替換也會出現丟失尾部換行符的情況。 > ```bash > # cd "`pwd`" # 你是不是認為這條語句在任何情況下都不會出現錯誤? > # 但事實卻不是這樣的。 > > mkdir 'dir with trailing newline > ' > > cd 'dir with trailing newline > ' > > cd "`pwd`" # Bash 會出現如下錯誤提示: > # bash: cd: /tmp/file with trailing newline: No such file or directory > > cd "$PWD" # 這樣寫是對的。 > > > > > > old_tty_setting=$(stty -g) # 保存舊的設置。 > echo "Hit a key " > stty -icanon -echo # 禁用終端的 canonical 模式。 > # 同時禁用 echo。 > key=$(dd bs=1 count=1 2> /dev/null) # 使用 'dd' 獲得鍵值。 > stty "$old_tty_setting" # 恢復舊的設置。 > echo "You hit ${#key} key." # ${#variable} 表示 $variable 中的字符個數。 > # > # 除了按下回車鍵外,其余情況都會輸出 "You hit 1 key." > # 按下回車鍵會輸出 "You hit 0 key." > # 因為唯一的換行符在命令替換中被丟失了。 > > # 這段代碼摘自 Stéphane Chazelas。 > ``` > ![caution](http://tldp.org/LDP/abs/images/caution.gif) 使用 `echo` 輸出未被引用的命令代換的變量時會刪掉尾部的換行。這可能會導致非常不好的情況出現。 > ```bash > dir_listing=`ls -l` > echo $dir_listing # 未被引用 > > # 你希望會出現按行顯示出文件列表。 > > # 但是,你卻看到了: > # total 3 -rw-rw-r-- 1 bozo bozo 30 May 13 17:15 1.txt -rw-rw-r-- 1 bozo > # bozo 51 May 15 20:57 t2.sh -rwxr-xr-x 1 bozo bozo 217 Mar 5 21:13 wi.sh > > # 所有換行都消失了。 > > > echo "$dir_listing" # 被引用 > # -rw-rw-r-- 1 bozo 30 May 13 17:15 1.txt > # -rw-rw-r-- 1 bozo 51 May 15 20:57 t2.sh > # -rwxr-xr-x 1 bozo 217 Mar 5 21:13 wi.sh > ``` 你甚至可以使用 [重定向](http://tldp.org/LDP/abs/html/io-redirection.html#IOREDIRREF) 或者 [`cat`](http://tldp.org/LDP/abs/html/basic.html#CATREF) 命令把一個文件的內容通過命令代換賦值給一個變量。 ```bash variable1=`<file1` # 將 "file1" 的內容賦值給 variable1。 variable2=`cat file2` # 將 "file2" 的內容賦值給 variable2。 # 使用 cat 命令會開一個新進程,因此執行速度會比重定向慢。 # 需要注意的是,這些變量中可能包含一些空格或者控制字符。 # 無需顯示的賦值給一個變量。 echo "` <$0`" # 輸出腳本自身。 ``` ```bash # 摘錄自系統文件 /etc/rc.d/rc.sysinit #+ (Red Hat Linux 發行版) if [ -f /fsckoptions ]; then fsckoptions=`cat /fsckoptions` ... fi # # if [ -e "/proc/ide/${disk[$device]}/media" ] ; then hdmedia=`cat /proc/ide/${disk[$device]}/media` ... fi # # if [ ! -n "`uname -r | grep -- "-"`" ]; then ktag="`cat /proc/version`" ... fi # # if [ $usb = "1" ]; then sleep 5 mouseoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=02"` kbdoutput=`cat /proc/bus/usb/devices 2>/dev/null|grep -E "^I.*Cls=03.*Prot=01"` ... fi ``` > ![caution](http://tldp.org/LDP/abs/images/caution.gif) 盡量不要將一大段文字賦值給一個變量,除非你有足夠的理由。也絕不要將一個二進制文件的內容賦值給一個變量。 > 樣例 12-1. 蠢蠢的腳本 > > ```bash > #!/bin/bash > # stupid-script-tricks.sh: 不要在自己的電腦上嘗試。 > # 摘自 "Stupid Script Tricks" 卷一。 > > exit 99 ### 如果你有膽,就注釋掉這行。:) > > dangerous_variable=`cat /boot/vmlinuz` # 壓縮的 Linux 內核。 > > echo "string-length of \$dangerous_variable = ${#dangerous_variable}" > # $dangerous_variable 的長度為 794151 > # (更新版本的內核可能更大。) > # 與 'wc -c /boot/vmlinuz' 的結果不同。 > > # echo "$dangerous_variable" > # 不要作死。否則腳本會掛起。 > > > > # 將二進制文件的內容賦值給一個變量沒有任何意義。 > > exit 0 > ``` > 盡管腳本會掛起,但并不會出現緩存溢出的情況。而這正是像 Bash 這樣的解釋型語言相比起編譯型語言能夠提供更多保護的一個例子。 命令替換允許將 [循環](http://tldp.org/LDP/abs/html/loops1.html#FORLOOPREF1) 的輸出結果賦值給一個變量。這其中的關鍵在于循環內部的 [`echo`](http://tldp.org/LDP/abs/html/internal.html#ECHOREF) 命令。 樣例 12-2. 將循環的輸出結果賦值給變量 ```bash #!/bin/bash # csubloop.sh: 將循環的輸出結果賦值給變量。 variable1=`for i in 1 2 3 4 5 do echo -n "$i" # 在這里,'echo' 命令非常關鍵。 done` echo "variable1 = $variable1" # variable1 = 12345 i=0 variable2=`while [ "$i" -lt 10 ] do echo -n "$i" # 很關鍵的 'echo'。 let "i += 1" # i 自增。 done` echo "variable2 = $variable2" # variable2 = 0123456789 # 這個例子表明可以在變量聲明時嵌入循環。 exit 0 ``` > 命令替換能夠讓 Bash 做更多的事情。而這僅僅需要在書寫程序或者腳本時將結果輸出到標準輸出 `stdout` 中,然后將這些輸出結果賦值給變量即可。 > > ```c > #include <stdio.h> > > /* "Hello, world." C program */ > > int main() > { > printf( "Hello, world.\n" ); > return (0); > } > ``` > > ``` > bash$ gcc -0 hello hello.c > ``` > > ```bash > #!/bin/bash > # hello.sh > > greeting=`./hello` > echo $greeting > ``` > > ``` > bash$ sh hello.sh > Hello, world. > ``` > ![note](http://tldp.org/LDP/abs/images/note.gif) 在命令替換中,你可以使用 `$(...)` 來替代反引號。 > > ```bash > output=$(sed -n /"$1"/p $file) # 摘自 "grp.sh"。 > > # 將文本文件的內容賦值給一個變量。 > File_contents1=$(cat $file1) > File_contents2=$(<$file2) # 這么做也是可以的。 > ``` > > `$(...)` 和反引號在處理雙反斜杠上有所不同。 > > ``` > bash$ echo `echo \\` > > > bash$ echo $(echo \\) > \ > ``` > > `$(...)` 允許嵌套。[^3] > > ```bash > word_count=$( wc -w $(echo * | awk '{print $8}') ) > ``` > > 樣例 12-3. 尋找變位詞(anagram) > > ```bash > #!/bin/bash > # agram2.sh > # 嵌套命令替換的例子。 > > # 其中使用了作者寫的工具包 "yawl" 中的 "anagram" 工具。 > # http://ibiblio.org/pub/Linux/libs/yawl-0.3.2.tar.gz > # http://bash.deta.in/yawl-0.3.2.tar.gz > > E_NOARGS=86 > E_BADARG=87 > MINLEN=7 > > if [ -z "$1" ] > then > echo "Usage $0 LETTERSET" > exit $E_NOARGS # 腳本需要命令行參數。 > elif [ ${#1} -lt $MINLEN ] > then > echo "Argument must have at least $MINLEN letters." > exit $E_BADARG > fi > > > > FILTER='.......' # 至少需要7個字符。 > # 1234567 > Anagrams=( $(echo $(anagram $1 | grep $FILTER) ) ) > # $( $( 嵌套命令集 ) ) > # ( 賦值給數組 ) > > echo > echo "${#Anagrams[*]} 7+ letter anagrams found" > echo > echo ${Anagrams[0]} # 第一個變位詞。 > echo ${Anagrams[1]} # 第二個變位詞。 > # 以此類推。 > > # echo "${Anagrams[*]}" # 將所有變位詞在一行里面輸出。 > > # 可以配合后面的數組章節來理解上面的代碼。 > > # 建議同時查看另一個尋找變位詞的腳本 agram.sh。 > > exit $? > ``` 以下是包含命令替換的樣例: 1. [樣例 11-8](http://tldp.org/LDP/abs/html/loops1.html#BINGREP) 2. [樣例 11-27](http://tldp.org/LDP/abs/html/testbranch.html#CASECMD) 3. [樣例 9-16](http://tldp.org/LDP/abs/html/randomvar.html#SEEDINGRANDOM) 4. [樣例 16-3](http://tldp.org/LDP/abs/html/moreadv.html#EX57) 5. [樣例 16-22](http://tldp.org/LDP/abs/html/textproc.html#LOWERCASE) 6. [樣例 16-17](http://tldp.org/LDP/abs/html/textproc.html#GRP) 7. [樣例 16-54](http://tldp.org/LDP/abs/html/extmisc.html#EX53) 8. [樣例 11-14](http://tldp.org/LDP/abs/html/loops1.html#EX24) 9. [樣例 11-11](http://tldp.org/LDP/abs/html/loops1.html#SYMLINKS) 10. [樣例 16-32](http://tldp.org/LDP/abs/html/filearchiv.html#STRIPC) 11. [樣例 20-8](http://tldp.org/LDP/abs/html/redircb.html#REDIR4) 12. [樣例 A-16](http://tldp.org/LDP/abs/html/contributed-scripts.html#TREE) 13. [樣例 29-3](http://tldp.org/LDP/abs/html/procref1.html#PIDID) 14. [樣例 16-47](http://tldp.org/LDP/abs/html/mathc.html#MONTHLYPMT) 15. [樣例 16-48](http://tldp.org/LDP/abs/html/mathc.html#BASE) 16. [樣例 16-49](http://tldp.org/LDP/abs/html/mathc.html#ALTBC) [^1]: 在命令替換中可以使用外部系統命令,[內建命令](http://tldp.org/LDP/abs/html/internal.html#BUILTINREF) 甚至是 [腳本函數](http://tldp.org/LDP/abs/html/assortedtips.html#RVT)。 [^2]: 從技術的角度來講,命令替換實際上是獲得了命令輸出到標準輸出的結果,然后通過賦值號將結果賦值給一個變量。 [^3]: 事實上,使用反引號進行嵌套也是可行的。但是 John Default 提醒到需要將內部的反引號進行轉義。<pre>word_count=\` wc -w \\\`echo * | awk '{print $8}'\\\` \`</pre>
                  <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>

                              哎呀哎呀视频在线观看