1. 程式人生 > >[拾 得]pipe和xargs的恩怨情仇

[拾 得]pipe和xargs的恩怨情仇

命令參數 字母 得到 實現 朋友 -i org 標準輸入 echo

技術分享                 Photo by Joshua Sortino on Unsplash 堅持知識分享,該文章由Alopex編著, 轉載請註明源地址: http://www.cnblogs.com/alopex/ 索引:
  • pipe 與 xargs 的用途
  • 一個head 例子的引入
  • STDIN 與 argument 的關系
  • 對pipe 與 xargs的總結
知識摘要:
  • 能夠理解 pipe 和 xargs 的作用
  • 可以理解 為什麽有了 pipe後我們還需要 xargs
  • 對 stdin , argument 和 option 有較為簡單的認識
    • 涉及命令 pipe(|) , xargs, head, echo, wc
相信接觸Linux的朋友們,常會用到以下兩個命令 pipe(|) 和 xargs.
  • pipe 與 xargs 的用途
pipe (|) : 其用途是, 將前一個命令執行得到的的結果,變為下一個命令的輸入. 我們結合pipe(管道)這個生動的形象,可以這樣"合理的"假設: 一個命令就是流水線上的一臺機器, 傳入的數據是加工的材料,pipe則是流水線上的運輸帶, 當我們傳入一個原料後,機器(命令),將按照我們的意願(命令的參數)對原料進行加工. 然而基於*inux的哲學, "Make each program do one thing well" -- by Doug McIlroy. 的思想, 我們的機器(命令),只能對原材料(傳入的數據)進行一項特定的加工, 假如我希望對加工後的材料再進行二次或多次加工呢? 這時,我們就需要一條傳輸帶(pipe), 將我們毛加工後的材料送往需要二次加工的機器上
xargs : 其用途是從標準輸入中"重構"和執行命令. 基於pipe上面流水線的比喻, xargs 我們可將其看作是流水線中的一臺機器 (但這臺機器有點特殊) 首先,像 grep, sed, awk 這些機器(命令)一般都能接收來自 pipe這個傳輸帶送過來的毛加工材料, 但是如果命令是cp , echo 等機器(命令), 卻不能接收這些加工材料,輕則無視它,嚴重的直接(罷工)報錯.這個時候就需要 xargs 這臺機器(命令)先對材料進行合適的加工,再交給這些挑剔的機器(命令) 其此, 在大多數Linux kernel(可使用命令 $ uname -r 查看 )為2.6.23之前的版本, 普遍無法執行大參數過長的命令. 這時借用xargs, 就能很好地規避這個問題, 實現命令的暢通執行.
到這,善於思考的你,可能就會有這樣一個疑問,是什麽造成毛加工(命令的輸出) 後的產品,得某些機器(命令)必須要讓xargs協助他們才能繼續工作呢?
  • 一個head命令的例子引入
我們先不忙著立刻去解答,先引出一個例子 <<聲明>>: 1.終端的提示符為 [>] 2.為了便於展示,這裏使用[head]命令讀取, 讀者可使用[cat]命令替換[head]命令, 道理是一樣的 > head file1 file2 ==> file1 <== I am file one. ==> file2 <== I am file two. #兩份文件, 以及裏面的內容 > > echo file1 file2 | head file1 file2 # 將echo的內容傳入管道, cat 命令處理後,得到的是 echo 的內容 > echo file1 file2 | xargs head ==> file1 <== I am file one. ==> file2 <== I am file two. # 將echo的內容傳給管道, 先由xargs處理, 再送給head命令處理, 打開了兩份文件的內容 真令人驚喜, 我們將同樣的內容送進管道符, 沒有經過xargs處理的數據, head命令直接將其打印到屏幕上了. 經過xargs處理後, 我們傳入的數據,變成了兩個文件的名字, head命令將兩個文件中的內容打印了出來. 這又產生一個疑問了, bash是如何知道,我們傳入的是普通字符串還是文件名的呢?
  • STDIN 與 argument 的關系
到這裏,我們不得不提,兩個重要的概念了,這是你每天在命令行上都會接觸到,但是常常會忽略的內容.STDIN 和 argument STDIN: Standard input (stdin) , 被稱為標準輸入數據流,通常是文本信息,也就是我們用鍵盤輸入的字符. 使用這個作為輸入信息時,需要程序(命令)對輸入的信息進行"讀"的操作. 然而並不是所有的程序(命令)都對能力處理流的輸入的, 例如 dir , ls 這些命令就無法處理輸入的流 例如我們希望能夠使用 echo 輸出 file1 這個字符串, 通過管道符,將其傳輸給 ls -l 處理, 希望它能返回出 file1文件的詳細列表信息 如果我們不假思索, 命令將被寫成這樣 > echo file1 | ls -l total 12 -rw-r--r-- 1 root root 0 Sep 24 08:28 a.txt -rw-r--r-- 1 root root 0 Sep 24 08:28 b.txt -rw-r--r-- 1 root root 0 Sep 24 08:28 c.txt -rw-r--r-- 1 root root 15 Oct 1 14:27 file1 -rw-r--r-- 1 root root 15 Oct 1 14:27 file2 -rw-r-xr-t 1 root root 0 Sep 24 11:09 hello -rwxr-xr-x 1 root root 322 Sep 24 12:01 useradd.sh # 這時得到的返回值是全部的文件, 而不是我們指定的file1. 這不是我們希望的 這是例子表明, 加工後的數據通過管道符傳送給後續的命令時, 傳輸的數據是標準輸入數據(stdin), 這種數據不能被所有的命令所處理 argument 一般被稱作參數, 由於跟在命令後的緣故,也被稱作命令參數. 它可以是一個文件名,或者是一個可以提供給命令進行加工得到輸出的需要的數據. 參數 會比較容易和另外一個概念混淆, 那就是 option(選項) 在Linux中,一般的選項都會有一個flag(-)後面跟著一個單一的字母, 以此來影響程序(命令)的操作,需要註意的是, 如果文件名中存在空格, 請使用 引號(單引號/雙引號) 將參數包裹起來,一名bash 無法識別 下面以一個例子說明 argument 和 option > wc -wl "file 1" "file 2" 1 4 file 1 1 4 file 2 2 8 total #以上輸入中 , [wc] 是命令 , [-wl] 是選項 ["file 1" "file 2"] 為參數 對於我們希望通過echo 輸入 file1 字符串, 傳給管道符,將其傳輸給 ls -l 處理 的問題, 由於這裏 ls 無法stdin進行處理, 我們必須使用xargs將 stdin 轉變為 argument 讓 ls 能識別 > echo file1 | xargs ls -l -rw-r--r-- 1 root root 15 Oct 1 15:06 file1
  • pipe 和 xargs 的總結
好了說了那麽多,我們對 pipe 和 xargs 進行一個總結吧 pipe 能將我們輸入的命令產生的輸出, 轉變為stdin(標準輸入) ,傳遞給下一個命令, 再又下一個命令對其進行下一步處理 xargs 由於某些命令不具備處理 stdin(標準輸入)的能力, 它們只能處理一些argument, xargs 這個時候就需要站出來, 為這些命令提供幫助, 讓後續的操作得以繼續完成. 問題的參考解答 1.是什麽造成毛加工(命令的輸出) 後的產品,得某些機器(命令)必須要讓xargs協助他們才能繼續工作呢?
  • 命令處理後的數據為stdin, 但是有些命令無法對stdin進行處理,他們必須依賴其他工具如 xargs 對其進行加工,使的加工後的數據適合他們處理
2.bash是如何知道,我們傳入的是普通字符串還是文件名的呢?
  • 僅上面的例子分析 , head 是一既能處理stdin 又能處理 argument 的命令. 由於輸出通過管道符後,得到的是stdin, 因此 file* 就會被當作流處理, head命令就把它打印處理
  • 當流經過了 xargs 處理後, 就稱為了head 的argument, 所以 head命令就以文件的方式對待它,並將文件的內容打印到屏幕上
參考網站: http://www.linfo.org/argument.html        Argument Definition https://www.wikiwand.com/en/Xargs        xargs https://my.oschina.net/asay/blog/789875        xargs 與 管道符的使用 https://www.wikiwand.com/en/Pipeline_(Unix)       pipeline https://www.wikiwand.com/en/Unix_philosophy       Unix philosophy https://superuser.com/questions/600253/why-is-xargs-necessary Why is xargs necessary? https://www.wikiwand.com/en/Standard_streams#/Standard_input_.28stdin.29 standard input https://unix.stackexchange.com/questions/46372/whats-the-difference-between-stdin-and-arguments-passed-to-command What‘s the difference between STDIN and arguments passed to command?

[拾 得]pipe和xargs的恩怨情仇