.txt
7日以上経過したファイルを削除するためにcronジョブを実行したいと思います。 2つのコマンドがあります。最初のコマンド:
/usr/bin/find /var/www/example.com/wp-content/targetdir -name "*.txt" -type f -mtime +7 -exec rm -f {} \;
2番目のコマンド:
/usr/bin/find /var/www/example.com/wp-content/targetdir -name "*.txt" -type f -mtime +7 -delete
.txt
どちらのコマンドも、7日以上経過したファイルを削除するために使用できます。最初のコマンドは次のように読みましたrace condition
。最初のコマンドよりも2番目のコマンドを使用すると、どのような利点があるかを詳しく説明しますか?他のものよりも1つを使用することの利点と欠点は何ですか?
答え1
私が見た大会は次のとおりです。Stefan Chazerasの口コミ別の問題:
-exec rm {} +
存在しない競合状態の脆弱性が存在する場合を参照してください。-delete
したがって、他の人が書き込むことができるディレクトリには使用しないでください。一部の調査結果はこれらの脆弱性を軽減する可能性があります-execdir
。
実際にはこの部分は見えませんが(*)、そこの競争は-exec rm
ファイルのフルパスがどのように渡されるかと関連しており、その過程でツリーが再び巡回することになることがわかりますrm
。
find
ツリーを巡回し、コマンドラインで提供されている条件を評価した後、ツリーを再度巡回しますが、与えられた条件をrm
知らないので、find
今は確認しません。-delete
とを使用してツリーを参照し、-execdir
指定find
されたチェックを実行してからファイルを削除し、常にディレクトリのファイル記述子を開いたままにします。
find
ファイルまたはディレクトリの条件が評価される時間と実行される時間の間に誰かが介入して、ファイルまたはrm
ディレクトリの名前を変更できます。したがって、次のようになります。
- ルート実行
find . -type f -user joe -exec rm -f {} \;
find
./this/
ユーザーが所有するいくつかのファイルを含むディレクトリを実行して検索します。joe
- 別のユーザーが名前を変更し、
./this
同じ名前で別の場所を指すシンボリックリンクを作成します。 find
Runを実行し、rm -f ./this/hello.txt
シンボリックリンクをたどります。
hello.txt
これで、ユーザーだけでなく誰でも所有できるようになります。joe
これはfind
起動後も同様で、root
シンボリックrm
リンクの反対側にあるファイルを幸せに削除します。これは古典ですTOCTTOU(使用時間確認時間)の脆弱性。
より悪い例を挙げることができますが、これは一般的な考えです。
orを使用すると、ディレクトリ名が変更されても-delete
開いたファイル記述子がまだ同じディレクトリを指すため、これは発生しません。-execdir
ランタイムは、作業ディレクトリをそのディレクトリに設定し(システムコールは名前の参照なしでファイルディスクリプタを介して作業ディレクトリを変更します)、同様にインクルードディレクトリに関連付けられている名前を削除(使用)します。find
./this
-execdir
rm
fchdir()
-delete
unlinkat()
デフォルトでは(つまり、この-L
オプションがない場合)、ディレクトリツリーをナビゲートしたfind
ときに見つかったシンボリックリンクは続きません。rm
これは基本的なシステムコールへのパスのみを渡し、通常どおりシンボリックリンクに従うので、ここでは役に立ちません。これは、置き換えられるディレクトリ(./this
上記)がSymlink(または他のディレクトリ)で置き換えられる実際のディレクトリでなければならず、Symlinkが他のシンボリックリンクで置き換えられないことを意味します。
(*)この投稿を書いてから20分後にStéphaneの回答(下記リンク)へ同じ民族問題を説明するGNUマニュアルリンク。 (ため息をつく。)
-delete
暗示-depth
と製造された問題は-prune
それとは何の関係もなく、競争条件ではありません。これは-deleteオプションを使用して検索すると/save/ディレクトリ内のファイルが削除されますが、削除オプションなしで検索するとそのファイルが見つからないのはなぜですか?GNU coreutilsからfind
エラーメッセージが表示されたようです:
$ find a -name foo -prune -o -name hello.txt -delete
find: The -delete action automatically turns on -depth, but -prune does nothing when -depth is in effect. If you want to carry on anyway, just explicitly use the -depth option.
もう1つの違いは、ある程度普遍的にサポートされていても、-exec rm -f -- {} +
標準ツールではなく標準ツールのみを使用することです。-delete
たとえば、FreeBSDとGNUはこれをサポートしますが、Busyboxはサポートしません。望むより:検索: "-exec rm {};"対「-delete」 - 電子が広く推奨されているのはなぜですか?superuser.comから。