Shell-Script
這個使用“find … -exec sh -c ‘…’ sh {} +”的查找命令如何工作?
@StephaneChazelas 對此問答發布了以下解決方案:使用“find -exec {} +”時遇到一些問題。
$ find . -iname "*.extension" -exec sh -c ' exec <command> "$@" <additional parameters>' sh {} +
這裡到底發生了什麼?最後一個具體是
sh {}
做什麼的?似乎它只是為了安撫 find 的-exec
命令,以便它有事可做,一個 NOOP。我可以很容易地把它放在
echo {}
那裡,它似乎工作得很好。
語法是:
find ... -exec cmd {} +
find
將根據其中的條件找到許多文件,...
並cmd
以該文件路徑列表作為參數執行,在不超過命令參數大小限制的情況下盡可能多地執行。如果需要,它可能會拆分文件列表並
cmd
多次呼叫。例如,它最終可能會呼叫:cmd ./file1 ./file2 ... ./file3000 cmd ./file3001 ./file3002 ... ./file4321
一個限制是它
{}
必須是最後的。例如,您不能寫:find ... -exec cmd {} other args +
就像你可以用
';'
而不是'+'
.你可以寫:
find ... -exec echo foo {} +
但不是:
find ... -exec echo {} foo +
因此,如果您確實需要在
cmd
文件列表之後添加一些額外的參數,則必須求助於呼叫 shell。(您需要呼叫 shell 的其他原因是任何時候需要使用 shell 功能,如重定向、管道、一些字元串擴展……)在
sh -c 'inline-script' x a b c
, 對於inline-script
,$0
isx
,$1
isa
,$2
isb
…"$@"
這三個參數的列表也是如此:a、b 和 c。所以在:find ... -exec sh -c 'cmd "$@" other arg' find-sh {} +
對於內聯腳本,
$0
(例如在顯示錯誤消息時使用)設置為find-sh
並且"$@"
是文件列表(find
擴展{}
為)。通過使用 shell 的
exec
特殊內置函式:find ... -exec sh -c 'exec cmd "$@" other arg' find-sh {} +
我們告訴 shell 不要派生一個額外的程序來執行
cmd
,而是在同一個程序中執行它(用該命令替換正在執行的 shell 程序)。一些 shellzsh
和一些實現ksh
隱式地為內聯腳本中的最後一個命令執行此操作(bash
當內聯腳本中只有一個命令時,如這裡)。