簡介
例如,下面的命令:
如果path目錄下檔案過多就會因為“參數列表過長”而報錯無法執行。但改用xargs以後,問題即獲解決。
本例中xargs將find產生的長串檔案列表拆散成多個子串,然後對每個子串調用rm。這樣要比如下使用find命令效率高的多。
上面這條命令會對每個檔案調用"rm"命令。當然使用新版的"find"也可以得到和"xargs"命令同樣的效果:
xargs的作用一般等同於大多數Unix shell中的反引號,但更加靈活易用,並可以正確處理輸入中有空格等特殊字元的情況。對於經常產生大量輸出的命令如find、locate和grep來說非常有用。
使用方法
用途
構造參數列表並運行命令。
語法
xargs [ -p ] [ -t] [ -e[ EOFString ] ] [ -EEOFString ] [ -i[ ReplaceString ] ] [ -IReplaceString ] [ -l [ Number ] ] [ -L Number ] [ -n Number [ -x ] ] [ -s Size ] [ Command [ Argument ... ] ]
註: 不要在小寫標誌和參數之間放置空格。
描述
生成的命令行長度是 Command 和每個作為字元串對待的 Argument(包括每個字元串的空位元組 終結符)的大小的總和(以位元組為單位)。xargs 命令限制命令行的長度。 當構造的命令行運行時,組合的 Argument 和環境列表 不能超出 ARG_MAX 位元組。在這個約束下,如果 不指定 -n 或 -s 標誌,預設命令行長度 至少是由 LINE_MAX 指定的值。
標誌
-e[EOFString] | 廢棄的標誌。請使用 -E 標誌。 將 EOFString 參數用作邏輯 EOF 字元串。如果不指定 -e 或 -E 標誌, 則假定下劃線(_)為邏輯 EOF 字元串。如果不指定 EOFString 參數,則禁用邏輯 EOF 字元串 能力,且下劃線按照字面含義使用。xargs 命令讀取標準輸入直到達到 EOF 或指定的字元串。 |
-E EOFString | 指定邏輯 EOF 字元串以替換預設的下劃線(_)。 xargs 命令讀取標準輸入直到達到 EOF 或指定的字元串。 |
-i[ReplaceString] | 廢棄的標誌。請使用 -I(大寫 i)標誌。 如果沒有指定 ReplaceString 參數, 則使用字元串 "{}"。 註:-I(大寫 i)和 -i 標誌是互相排斥的;最後指定的標誌生效。 |
-I ReplaceString | (大寫 i)。插入標準輸入的每一行作為 Command 參數的自變數,把它插入每個發生 ReplaceString 的 Argument 中。ReplaceString 不能在超過 5 個自變數中使用。 在每個標準輸入行開始的空字元被忽略。 每個 Argument 能包含一個或多個 ReplaceString,但不能大於 255 位元組。-I 標誌同樣打開 -x 標誌。註:-I(大寫 i)和 -i 標誌是互相排斥的;最後指定的標誌生效。 |
-l[Number] | (小寫的 L)。廢棄的標誌。請使用 -L 標誌。 如果沒有指定 Number 參數,使用預設值 1。-l 標誌同樣打開 -x 標誌。 註: -L、-I(小寫的 L)和 -n 標誌是互相排斥的;最後指定的標誌生效。 |
-L Number | 用從標準輸入讀取的指定行數的非空參數運行 Command 命令。如果保留少於指定的 Number,Command 參數 的最後調用可以有少數幾個參數行。行以第一個換行字元結束,除非該行的最後一個字元是一個空格 或制表符。後續的空格表示延續至下一個非空行。註: -L、-I(小寫的 L)和 -n 標誌是互相排斥的;最後指定的標誌生效。 |
-n Number | 運行 Command 參數,且使用儘可能多的標準輸入自變數,直到 Number 參數指定的最大值。如果滿足以下條件,則 xargs 命令使用 更少的自變數: |
-p | 詢問是否運行 Command 參數。 它顯示構造的命令行,後跟一個 ?...(問號和省略號)提示。輸入肯定的、特定於語言環境的回響 以運行 Command 參數。 任何其它回響都會引起 xargs 命令 跳過那個特定的參數調用。每個調用都將詢問您。 -p 標誌同樣打開 -t 標誌。 |
-s Size | 設定構造的 Command 行的最大 總大小。Size 參數必須是正整數。如果滿足以下條件,則使用更少的自變數: |
-t | 啟用跟蹤方式,並在運行之前將構造的 Command 行回送到標準錯誤。 |
-x | 如果有任何 Command 行大於 -s Size 標誌指定的位元組數,停止運行 xargs 命令。如果指定 -I(大寫 i)或 -l(小寫 L)標誌,則打開 -x 標誌。如果 沒有指定 -i、-I(大寫 i)、-l(小寫 L)、-L 或 -n 標誌,則 Command 行的總長度必須 在 -s Size 標誌指定的限制內。 |
退出狀態
0 | 所有 Command 參數的調用 都返回退出狀態 0。 |
1-125 | 不能彙編滿足指定需求的命令行, 一個或多個 Command 參數的調用 返回一個非零的退出狀態,或發生一些其它的錯誤。 |
126 | Command 已找到但不能被調用。 |
127 | 找不到 Command。 |
如果不能彙編滿足指定需求的命令行, 則不能調用這個命令,命令的調用被一個信號終止,或以退出狀態 255 退出。xargs 命令將寫一條診斷訊息並 退出而不處理任何保留的輸入。
所在位置
/usr/bin/xargs | 包含 xargs 命令。 |
套用
示例1
1. 要對名稱在檔案中列出的檔案使用命令,輸入:
如果 cfiles 檔案包含下面的 文本:
main.c readit.cgettoken.cputobj.c
xargs 命令就構造並運行 下面的命令:
如果 cfiles 檔案包含的檔案名稱比在單一 shell 命令行上能處理的檔案名稱(最多 LINE_MAX)要多,xargs 命令會用後者運行 lint 命令。然後它使用餘下的檔案名稱構造並運 行另一個 lint 命令。 根據在 cfiles 檔案中列出的名稱, 命令看起來可能類似於如下所示的內容:
該命令序列同用所有的檔案名稱運行 lint 命令一次不完全一樣。lint 命令檢查檔案之間的交叉參考。然而,在這個示例中, 它不能在 main.c 和 fltadd.c 檔案之間,或任意兩個在分開的命令行上列出的檔案之間進行檢查。
由於這個原因, 僅當所有的檔案名稱都在一行上列出時,才可能運行命令。要將這個指定 到 xargs命令,通過輸入以下命令使用 -x 標誌:
如果在檔案 cfiles 中的所有檔案名稱沒有在一個命令行上列出,xargs 命令顯示一條錯誤訊息。
2. 要構造包含一定數量檔案名稱的命令,輸入:
該命令序列構造並運行每個包含兩個檔案名稱的 diff 命令(-n 2):
-t 標誌使 在運行 xargs 命令前顯示每個命令, 這樣您可以看到正在發生的事件。<<EOF 和 EOF 模式匹配字元定義 一個 here document, 它把在結尾行之前輸入的文本用作對 xargs 命令的標準輸入。
3. 要把檔案名稱插入命令行的中間,輸入:
該命令序列通過在每個名字結尾添加 .old 來重命名在當前目錄里的所有檔案。-I 標誌告訴 xargs 命令插入有{} (花括弧)出現的 ls 目錄列表的每一行。 如果當前目錄包含檔案 chap1、chap2 和 chap3,這會構造下面的命令:
4. 要對個別選擇的檔案運行命令,輸入:
該命令序列允許選擇檔案以添加到 lib.a 庫。-p 標誌告訴 xargs 命令去顯示每個它構造的 ar命令,並詢問是否想運行它。輸入 y 來運行命令。如果不想運行這個命令按任意其它鍵。
會顯示一些類似於下面的內容:
5. 要構造包含特定數量自變數的命令並將那些自變數插入一個命令行的中間,輸入:
如果當前目錄 包含從 chap1 到 chap10 的檔案,構造的輸出將會是下列內容:
示例2
xargs - build and execute command lines from standard input
在使用find命令的-exec選項處理匹配到的檔案時,find命令將所有匹配到的檔案一起傳遞給exec執行。但有些系統對能夠傳遞給exec的命令長度有限制,這樣在find命令運行幾分鐘之後,就會出現溢出錯誤。錯誤信息通常是“參數列太長”或“參數列溢出”。這就是xargs命令的用處所在,特別是與find命令一起使用。
find命令把匹配到的檔案傳遞給xargs命令,而xargs命令每次只獲取一部分檔案而不是全部,不像-exec選項那樣。這樣它可以先處理最先獲取的一部分檔案,然後是下一批,並如此繼續下去。
在有些系統中,使用-exec選項會為處理每一個匹配到的檔案而發起一個相應的進程,並非將匹配到的檔案全部作為參數一次執行;這樣在有些情況下就會出現進程過多,系統性能下降的問題,因而效率不高;
而使用xargs命令則只有一個進程。另外,在使用xargs命令時,究竟是一次獲取所有的參數,還是分批取得參數,以及每一次獲取參數的數目都會根據該命令的選項及系統核心中相應的可調參數來確定。
來看看xargs命令是如何同find命令一起使用的,並給出一些例子。
下面的例子查找系統中的每一個普通檔案,然後使用xargs命令來測試它們分別屬於哪類檔案
在整個系統中查找記憶體信息轉儲檔案(core dump) ,然後把結果保存到/tmp/core.log 檔案中:
上面這個執行太慢,我改成在當前目錄下查找
在當前目錄下查找所有用戶具有讀、寫和執行許可權的檔案,並收回相應的寫許可權:
用grep命令在所有的普通檔案中搜尋hostname這個詞:
用grep命令在當前目錄下的所有普通檔案中搜尋hostnames這個詞:
注意,在上面的例子中, \用來取消find命令中的*在shell中的特殊含義。find命令配合使用exec和xargs可以使用戶對所匹配到的檔案執行幾乎所有的命令。