2009-12-13 144 views
20

我對此非常困惑。需要一些澄清。瞭解UNIX命令xargs

例1:

pgrep string | xargs ps 

例2:

find . | xargs grep whatever 

從例1,我收集是這樣:

搜索一個 「串」,這是運行過程的名稱的一部分,並返回所有匹配的process-id到'xargs ps' - >它只是附加PS的比賽(這是進程的ID本身),以獲得輸出相同:

ps <processid> 

有人能解釋xargs的確實在這種情況下?

從例2,我收集是這樣:

這是從當前工作目錄中尋找一些「串」遞歸。 在這裏,'xargs'的工作方式到底如何?我認爲'xargs'重複將數據從標準輸入附加到xargs(通常是UNIX命令本身)的'參數'。

從xargs的()手冊頁:

xargs的讀取從標準輸入項目,由空格分隔(可 保護與雙或單引號或反斜槓)或換行符和 執行命令(默認爲/ bin/echo),其中任何 初始參數後跟從標準輸入讀取的項目一次或多次。標準輸入上的空白行 被忽略。

+0

xargs的作用類似於「命令託換」(與巴什至少)得到的ARG_MAX當前值。它將多行結果(垂直)轉換爲標記參數的單行列表(水平)。 (請注意,在將其傳遞給xargs之前,您可能會過濾一些結果(使用sed for ex))。 Plus xargs處理Linux內核2.6.23之前可能會出現的«_too much arguments_»錯誤(參見[wikipedia](https://en.wikipedia.org/wiki/Xargs))。這裏是[另一個有用的線程](http://unix.stackexchange.com/questions/24954/when-is-xargs-需要) – Stphane

回答

37

一般而言xargs的使用這樣

PROG | xargs實用程序

其中prog預計會輸出一個或多個換行/空格分隔結果。訣竅是,xargs不! nessarly電話實用程序一次爲每個結果,而不是它 拆分結果列表成爲子列表和調用實用程序爲每個子列表。如果您想強制xargs爲每個單一結果調用實用程序,您需要使用xargs -L1來調用它。

注意xargs的承諾你發送到實用子表短於ARG_MAX(這是如何避免那些可怕的參數列表長錯誤)。您可以使用getconf ARG_MAX

+1

嗯,這是我可以涉及的事情,但現在變得更加混亂。我知道xargs在那裏的基本原因,但是當我看到它被用於多個目的(以不同的方式)時,它會變得複雜。 – halluc1nati0n

+7

請考慮此命令「find/etc -type d -depth 1 | xargs echo」它打印/ etc文件夾中的所有目錄(但不是它們的子目錄)。由於echo需要多個參數,結果是一個長行「/ etc/dir1/etc/dir2 ...」。如果你改爲調用「find/etc -type d -depth 1 | xargs -L1 echo」,那麼echo會爲每個結果調用一次,從而導致/ etc中的每個目錄都自行打印在一行上。 –

+0

如何將命令或選項傳遞給實用程序?說,我想運行uglifyjs並指定並輸出進入xargs的輸入文件夾? http://stackoverflow.com/questions/43149786/how-to-process-files-in-nested-directories – Costa

2

xargs的通常用於組參數一起,讓你沒得到,當你通過大量的參數命令

6
$ echo 'line1 
> line2 
> line3 
> ... 
> lineN ' | xargs cmd1 -a -b 

將導致其出現了「太多的參數」的錯誤:

$ cmd1 -a -b line1 line2 line3 ... lineN 

xargs將打破cmd1 ...cmd1幾個處決如果行數變得太大。

xargs可用於許多其他與傳遞stdin行作爲位置參數相關的任務。查看xargs(1)中的首選-P選項,以並行運行多個命令實例。

1
#!/bin/sh 
#script to echo out the arguments 1 at a time! 
for a in $* 
do 
    echo $a 
done 

命令

$sh myscript 1 2 3 4 5 

將產生

1 
2 
3 
4 
5 

$sh myscript 1 2 3 4 5 6 7 8 9 10 11 
因爲參數的最大數量

將無法​​正常工作超過(IM實際上並不知道是什麼最大值是,但可以說是10這個例子!)

爲了解決這個問題,我們可以使用

#!/bin/sh 
#script to echo out the arguments 1 at a time! 
for a in $* 
do 
    echo $a | xargs echo 
done 

那麼我們就可以運行它像這樣

$sh myscript "1 2 3 4 5" "6 7 8 9 10 11" 

,並得到正確的結果,因爲剛好有2個參數

+2

我不知道什麼是最大值,但它絕對不是10.你可以使用$ @而不是$ *。這不是一個很好的例子,如何使用xargs – ghostdog74

9

xargs做的一個很好的例子是嘗試使用find獲取目錄中每個文件的排序校驗和。

find . | cksum | sort 

只返回一個校驗和,它不清楚它的校驗和是什麼。不是我們想要的。管道將查找到的stdout發送到cksum的stdin。 cksum真正需要的是命令行參數列表,例如

cksum file001.blah file002.blah file003.blah 

將報告三行,每個文件一行,並帶有所需的校驗和。 Xargs執行這個魔術 - 將前一個程序的stdout轉換爲一個臨時和隱藏的命令行,以供下一個程序使用。可用的命令行是:

find . | xargs cksum | sort 

注意xargs和cksum之間沒有管道。

+1

順便說一句,這是我的配方中找到重複文件在兩個或多個目錄中的主要成分,即使它們的名稱不同。 – DarenW

+0

感謝您的洞察力,並向xargs添加冗長的命令行動。找 。 | xargs --verbose cksum |排序 – kumar