
findutilsのマニュアルで学んだ。xargs
多くのアプリケーションでは、ファイル名に特殊文字が含まれているため、xargsがファイルを処理できない場合、一部のデータが失われる可能性があります。
ただし、これは名前を区切るためにスペースを使用した場合に発生する可能性がある問題の極端な例です。 cronで毎日次のコマンドを実行すると、すべてのユーザーがシステム上のすべてのファイルを削除できます。
find / -name ’#*’ -atime +7 -print | xargs rm
たとえば、次のようにできます。
eg$ echo > ’# vmunix’
その後、スケジュールされたタスクがあります。/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
ファイルを削除するには?
ありがとうございます。
答え1
問題は、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'? $
./a
、、、、./b
および5つのファイルを削除しようとしましたc
。./d
e
したがって、ファイル名にスペースと改行がある場合、2つの引数がコマンドに渡されます。
標準ソリューションは次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文字(ファイル名の一部にすることはできません)が区切り文字として使用され、スペースは重要ではありません。
答え2
問題の残りの半分は対応方法です。答えは\0
、空白の区切り文字の代わりに区切り文字を使用することです(-0
ファイル名には許可されず、許可されていない唯一の文字です。/
ファイル名の一部ですが特別な目的があります)。
これを行うには、コードを次のように変更します。
find … -print0 | xargs -0 …