“find -exec”如何傳遞帶空格的文件名?
如果我有一個目錄,其中包含一些名稱有空格的文件,例如
$ ls -1 dir1 file 1 file 2 file 3
我可以成功地將它們全部複製到另一個目錄,如下所示:
$ find dir1 -mindepth 1 -exec cp -t dir2 {} +
但是,輸出
find dir1 -mindepth 1
包含未轉義的空格:$ find dir1 mindepth 1 dir1/file 1 dir1/file 3 dir1/file 3
如果我使用
print0
而不是$ find dir1 mindepth 1 -print0 dir1/file 1dir1/file 2dir1/file 3
要使用 手動複製這些文件
cp
,我需要轉義空格;cp
但是當’s aguments 來自時,這似乎是不必要的find
,無論我是使用+
還是\;
在命令末尾。這是什麼原因?
find
命令直接執行命令。該命令(包括文件名參數)不會被 shell 或任何其他可能修改文件名的東西處理。這是非常安全的。您是正確的,不需要轉義命令行
{}
上由 表示的文件名。find
find
將磁碟中的原始文件名直接傳遞到-exec
命令的內部參數列表中,在您的情況下是cp
命令。
問題分為兩部分:
- 如何設法呼叫程序而不會 遇到文件名中嵌入空格的問題,以及
find``-exec
- 有什麼好處
-print0
?首先,
find
是進行系統呼叫,實際上是一組相關呼叫中的一個,稱為“exec”。它將文件名作為參數直接傳遞給此呼叫,然後直接傳遞(在創建新程序之後)而不會失去有關文件名的資訊。SVR4
find
實用程序的一個特點是-exec
主要的 + 終止符。這允許將包含特殊字元(尤其是換行符)的文件名組合在一起,而不會出現此類文件名通過管道傳輸到xargs
. 其他實現添加了其他方法來解決此問題,特別是-print0
使用空字節終止符編寫文件名的主節點。此處考慮過,但未採用。使用空終止符意味著任何要處理 find-print0
輸出的實用程序都必須添加一個新選項來解析它現在正在讀取的空終止符。“特別是
-print0
主要的”指的是 GNUfind
,xargs
它以不同的方式解決問題。FreeBSDfind
和xargs
. 如果您在呼叫中添加了一個-0
選項(參見手冊頁)xargs
,則該程序接受以“空字節”字元結尾的行。反過來,xargs
呼叫exec -functions 來完成它的工作。-print0
和-0
特性與特性之間的主要區別在於+
前者通過管道傳遞文件名,而後者不傳遞。開發人員幾乎可以找到任何功能的用途;管道也不例外。回到 OP 的範例,該範例使用: 在POSIX cp中找不到的
-t
選項。相反,它是GNU cp提供的擴展(又稱“非標準功能”) 。的擴展不會改進這個例子,但在其他情況下可以有效地使用它——請記住,存在GNU接受的可移植替代方案。cp``-0``xargs``+``find