Xargs
xargs
如何處理 find
提供的文件名,這可能會導致問題?
來自 findutils 的手冊
xargs
在許多應用程序中,如果 xargs 因文件名稱包含特殊字元而無法處理文件,則可能會失去一些數據。
但是,這裡是使用空格分隔的名稱可能導致的問題的一個極端範例。如果每天從 cron 執行以下命令,則任何使用者都可以刪除系統上的任何文件:
find / -name ’#*’ -atime +7 -print | xargs rm
例如,您可以執行以下操作:
eg$ echo > ’# vmunix’
然後 cron將刪除 /vmunix,如果它以 / 作為目前目錄執行 xargs 。
要刪除其他文件,例如 /u/joeuser/.plan,您可以這樣做:
eg$ mkdir ’# ’ eg$ cd ’# ’ eg$ mkdir u u/joeuser u/joeuser/.plan’ ’ eg$ echo > u/joeuser/.plan’ /#foo’ eg$ cd .. eg$ find . -name ’#*’ -print | xargs echo ./# ./# /u/joeuser/.plan /#foo
在上面的範例中,如何
xargs
處理由 提供的文件名find
,以及如何刪除文件?謝謝。
問題在於如何
xargs
讀取輸入並將其傳遞給命令。我們可以很容易地看到這一點
rm -i
$ touch a 'b c' 'd > e' $ find -type f | cat ./d e ./b c ./a $ find -type f | xargs rm -i rm: cannot remove './d': No such file or directory rm: cannot remove 'e': No such file or directory rm: cannot remove './b': No such file or directory rm: cannot remove 'c': No such file or directory rm: remove regular empty file './a'? $
請注意,我們嘗試刪除 5 個文件;
./a
,./b
,c
,./d
, 和e
因此,文件名中的空格和換行符都會導致將兩個參數傳遞給命令。
標準解決方案是使用
find -print0
和xargs -0
$ find -type f -print0 | xargs -0 rm -i rm: cannot remove '.': Is a directory rm: remove regular empty file './d\ne'? rm: remove regular empty file './b c'? rm: remove regular empty file './a'? $
現在 NUL 字元(不能是文件名的一部分)用作分隔符,並且空格不重要。