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

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 第二十三章. 進程替換 用[管道](http://tldp.org/LDP/abs/html/special-chars.html#PIPEREF) 將一個命令的 ```標準輸出``` 輸送到另一個命令的 ```標準輸入``` 是個強大的技術。但是如果你需要用管道輸送_多個_命令的 ```標準輸出``` 怎么辦?這時候 _進程替換_ 就派上用場了。 _進程替換_ 把一個(或多個)[進程](http://tldp.org/LDP/abs/html/special-chars.html#PROCESSREF) 的輸出送到另一個進程的 ```標準輸入```。 **樣板** 命令列表要用括號括起來 ``` >(command_list) <(command_list) ``` 進程替換使用 ```/dev/fd/<n>``` 文件發送括號內進程的結果到另一個進程。[1] <img src="http://tldp.org/LDP/abs/images/caution.gif">"<"或">"與括號之間沒有空格,加上空格或報錯。 ``` bash$ echo >(true) /dev/fd/63 bash$ echo <(true) /dev/fd/63 bash$ echo >(true) <(true) /dev/fd/63 /dev/fd/62 bash$ wc <(cat /usr/share/dict/linux.words) 483523 483523 4992010 /dev/fd/63 bash$ grep script /usr/share/dict/linux.words | wc 262 262 3601 bash$ wc <(grep script /usr/share/dict/linux.words) 262 262 3601 /dev/fd/63 ``` <img src="http://tldp.org/LDP/abs/images/note.gif">Bash用兩個文件描述符創建管道,```--fIn 和 fOut--``` 。[true](http://tldp.org/LDP/abs/html/internal.html#TRUEREF) 的```標準輸入```連接 fOut(dup2(fOut, 0)),然后Bash 傳遞一個 ```/dev/fd/fIn``` 參數給 **echo** 。在不使用 ```/dev/fd/<n>``` 的系統里,Bash可以用臨時文件(感謝 S.C. 指出這點)。 進程替換可以比較兩個不同命令的輸出,或者同一個命令使用不同選項的輸出。 ``` bash$ comm <(ls -l) <(ls -al) total 12 -rw-rw-r-- 1 bozo bozo 78 Mar 10 12:58 File0 -rw-rw-r-- 1 bozo bozo 42 Mar 10 12:58 File2 -rw-rw-r-- 1 bozo bozo 103 Mar 10 12:58 t2.sh total 20 drwxrwxrwx 2 bozo bozo 4096 Mar 10 18:10 . drwx------ 72 bozo bozo 4096 Mar 10 17:58 .. -rw-rw-r-- 1 bozo bozo 78 Mar 10 12:58 File0 -rw-rw-r-- 1 bozo bozo 42 Mar 10 12:58 File2 -rw-rw-r-- 1 bozo bozo 103 Mar 10 12:58 t2.sh ``` 進程替換可以比較兩個目錄的內容——來檢查哪些文件在這個目錄而不在那個目錄。 ``` diff <(ls $first_directory) <(ls $second_directory) ``` 進程替換的一些其他用法: ``` read -a list < <( od -Ad -w24 -t u2 /dev/urandom ) # 從 /dev/urandom 讀取一個隨機數列表 #+ 用 "od" 處理 #+ 輸送到 "read" 的標準輸入. . . # 來自 "insertion-sort.bash" 示例腳本。 # 致謝:JuanJo Ciarlante。 ``` ``` PORT=6881 # bittorrent(BT端口) # 掃描端口,確保沒有惡意行為 netcat -l $PORT | tee>(md5sum ->mydata-orig.md5) | gzip | tee>(md5sum - | sed 's/-$/mydata.lz2/'>mydata-gz.md5)>mydata.gz # 檢查解壓縮結果: gzip -d<mydata.gz | md5sum -c mydata-orig.md5) # 對原件的MD5校驗用來檢查標準輸入,并且探測壓縮當中出現的問題。 # Bill Davidsen 貢獻了這個例子 #+ (ABS指南作者做了輕微修改)。 ``` ``` cat <(ls -l) # 等價于 ls -l | cat sort -k 9 <(ls -l /bin) <(ls -l /usr/bin) <(ls -l /usr/X11R6/bin) # 列出 3 個主要 'bin' 目錄的文件,按照文件名排序。 # 注意,有三個(數一下)單獨的命令輸送給了 'sort'。 diff <(command1) <(command2) # 比較命令輸出結果的不同之處。 tar cf >(bzip2 -c > file.tar.bz2) $directory_name # 調用 "tar cf /dev/fd/?? $directory_name",然后 "bzip2 -c > file.tar.bz2"。 # # 因為 /dev/fd/<n> 系統特性 # 不需要在兩個命令之間使用管道符 # # 這個可以模擬 # bzip2 -c < pipe > file.tar.bz2& tar cf pipe $directory_name rm pipe # 或者 exec 3>&1 tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&- exec 3>&- # 致謝:Stéphane Chazelas ``` 在子shell中 [echo 命令用管道輸送給 while-read 循環](http://tldp.org/LDP/abs/html/gotchas.html#BADREAD0)時會出現問題,下面是避免的方法: **例23-1 不用 fork 的代碼塊重定向。** ``` #!/bin/bash # wr-ps.bash: 使用進程替換的 while-read 循環。 # 示例由 Tomas Pospisek 貢獻。 # (ABS指南作者做了大量改動。) echo echo "random input" | while read i do global=3D": Not available outside the loop." # ... 因為在子 shell 中運行。 done echo "\$global (從子進程之外) = $global" # $global (從子進程之外) = echo; echo "--"; echo while read i do echo $i global=3D": Available outside the loop." # ... 因為沒有在子 shell 中運行。 done < <( echo "random input" ) # ^ ^ echo "\$global (使用進程替換) = $global" # 隨機輸入 # $global (使用進程替換)= 3D: Available outside the loop. echo; echo "##########"; echo # 同樣道理 . . . declare -a inloop index=0 cat $0 | while read line do inloop[$index]="$line" ((index++)) # 在子 shell 中運行,所以 ... done echo "OUTPUT = " echo ${inloop[*]} # ... 什么也沒有顯示。 echo; echo "--"; echo declare -a outloop index=0 while read line do outloop[$index]="$line" ((index++)) # 沒有在子 shell 中運行,所以 ... done < <( cat $0 ) echo "OUTPUT = " echo ${outloop[*]} # ... 整個腳本的結果顯示出來。 exit $? ``` 下面是個類似的例子。 **例 23-2. 重定向進程替換的輸出到一個循環內** ``` #!/bin/bash # psub.bash # 受 Diego Molina 啟發(感謝!)。 declare -a array0 while read do array0[${#array0[@]}]="$REPLY" done < <( sed -e 's/bash/CRASH-BANG!/' $0 | grep bin | awk '{print $1}' ) # 由進程替換來設置'read'默認變量($REPLY)。 #+ 然后將變量復制到一個數組。 echo "${array0[@]}" exit $? # ====================================== # # 運行結果: bash psub.bash #!/bin/CRASH-BANG! done #!/bin/CRASH-BANG! ``` 一個讀者發來一個有趣的進程替換例子,如下: ``` # SuSE 發行版中提取的腳本片段: # --------------------------------------------------------------# while read des what mask iface; do # 一些命令 ... done < <(route -n) # ^ ^ 第一個 < 是重定向,第二個是進程替換。 # 為了測試,我們讓它來做點兒事情。 while read des what mask iface; do echo $des $what $mask $iface done < <(route -n) # 輸出內容: # Kernel IP routing table # Destination Gateway Genmask Flags Metric Ref Use Iface # 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo # --------------------------------------------------------------# # 正如 Stéphane Chazelas 指出的, #+ 一個更容易理解的等價代碼如下: route -n | while read des what mask iface; do # 通過管道輸出設置的變量 echo $des $what $mask $iface done # 這段代碼的結果更上面的相同。 # 但是,Ulrich Gayer 指出 . . . #+ 這段簡化版等價代碼在 while 循環里用了子 shell, #+ 因此當管道終止時變量都消失了。 # --------------------------------------------------------------# # 然而,Filip Moritz 說上面的兩個例子有一個微妙的區別, #+ 見下面的代碼 ( route -n | while read x; do ((y++)); done echo $y # $y is still unset while read x; do ((y++)); done < <(route -n) echo $y # $y has the number of lines of output of route -n ) # 更通俗地說(譯者注:原文本行少了注釋符) ( : | x=x # 似乎啟動了子 shell ,就像 : | ( x=x ) # 而 x=x < <(:) # 并沒有。 ) # 這個方法在解析 csv 和類似格式時很有用。 # 也就是在效果上,原始 SuSE 系統的代碼片段就是做這個用的。 ``` 注解 [1] 這個與命名管道(使用臨時文件)的效果相同,而且事實上,進程替換也曾經用過命名管道。
                  <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>

                              哎呀哎呀视频在线观看