2016-02-23 20 views
4

我是bash的新手,我想了解使用xargs,這對我仍然不清楚。例如:何時使用xargs管道時?

history | grep ls 

這裏我正在尋找我的歷史記錄中的命令ls。在這個命令中,我沒有使用xargs,它工作正常。

find /etc - name "*.txt" | xargs ls -l 

我這一次,我不得不使用xargs,但我仍然無法理解的差異,我不能夠正確地決定何時使用xargs,何時不。

+0

底線是命令行命令可以採用的大小的限制。 (這是一個硬編碼的數字,通常是'128KiB')參見[**什麼定義了單個命令的最大尺寸?**](http://unix.stackexchange.com/questions/120642/what-defines-the-最大尺寸換一個命令單參數)。當你的命令行超過這個大小時,你的選擇是使用'xargs',這會破壞它併爲你處理命令。 –

回答

3

走要回答你的問題學習GNU並行,xargs可以用來當你需要從一個命令的輸出,並用它作爲參數傳遞給另一個。在第一個示例中,grep從標準輸入中獲取數據,而不是作爲參數。所以,xargs是不需要的。

xargs從標準輸入獲取數據並執行命令。默認情況下,數據作爲參數附加到命令的末尾。它可以插入任何地方,但使用佔位符輸入。傳統的佔位符是{};利用這一點,你的榜樣命令可能隨後被寫成:

find /etc -name "*.txt" | xargs -I {} ls -l {} 

如果您有/etc 3個文本文件,你會得到每一個完整的目錄列表。當然,你可以簡單地寫下ls -l /etc/*.txt並省去了麻煩。

另一個示例讓您重命名這些文件,並要求佔位符{}使用兩次。

find /etc -name "*.txt" | xargs -I {} mv {} {}.bak 

這些都是不好的例子,只要你有一個包含空格的文件名就會中斷。您可以通過告訴find使用空字符分隔文件名來解決該問題。

find /etc -print0 -name "*.txt" | xargs -I {} -0 mv {} {}.bak 

我個人的看法是,幾乎總有替代品使用xargs,你可以通過學習這些得到更好的服務。

0

讀取非NUL定界的輸入時,xargs(1)是危險的(損壞,可被利用等)。

如果您使用的是文件名,請使用find的-exec [command] {} +代替。 如果您可以獲得NUL分隔的輸出,請使用xargs -0

+0

@SaraHamad:您可以通過在您的cmd行中添加「-print0」來從您的find中獲得以null結尾的字符串。檢查你的手冊頁。 (大多數新版本都有它) – shellter

+0

IFS =讀取-r -d'行以確保讀取null分隔輸入? –

+0

@DirkHerrmann你是對的。雖然我是爲一般情況寫的。我根據你的評論刪除了這部分。 –

2

簡答題:暫時避免xargs。當您編寫數十或數百個腳本時返回到xargs

命令可以從參數獲得他們的投入(如rm bad_example),或者可以從stdin輸入(rm -i is_this_bad_too後不只是關於這個問題的Y,而且read answer)。其他命令(如grepsed)將查找參數,並在參數不顯示輸入時切換到輸入。
您的grep示例可以很好地從stdin中讀取,沒有什麼特別需要。
您的ls需要查找的輸出作爲參數。 xargs只是一種扭轉局面的方法。有關xargs的更多信息,請使用man xargs。替代方案:

find /etc -name "*.txt" -exec ls -l {} \; 
find /etc -name "*.txt" -ls 
ls -l $(find /etc -name "*.txt") 
ls /etc/*.txt 

第一次嘗試,看看此命令是最好的,當你在/ etc a nasty filename with spaces.txt