Cronジョブは7日を過ぎたすべてのファイルを削除します。 -exec rm -f{}\;

Cronジョブは7日を過ぎたすべてのファイルを削除します。 -exec rm -f{}\;

.txt7日以上経過したファイルを削除するために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ディレクトリの名前を変更できます。したがって、次のようになります。

  1. ルート実行find . -type f -user joe -exec rm -f {} \;
  2. find./this/ユーザーが所有するいくつかのファイルを含むディレクトリを実行して検索します。joe
  3. 別のユーザーが名前を変更し、./this同じ名前で別の場所を指すシンボリックリンクを作成します。
  4. findRunを実行し、rm -f ./this/hello.txtシンボリックリンクをたどります。

hello.txtこれで、ユーザーだけでなく誰でも所有できるようになります。joeこれはfind起動後も同様で、rootシンボリックrmリンクの反対側にあるファイルを幸せに削除します。これは古典ですTOCTTOU(使用時間確認時間)の脆弱性

より悪い例を挙げることができますが、これは一般的な考えです。

orを使用すると、ディレクトリ名が変更されても-delete開いたファイル記述子がまだ同じディレクトリを指すため、これは発生しません。-execdirランタイムは、作業ディレクトリをそのディレクトリに設定し(システムコールは名前の参照なしでファイルディスクリプタを介して作業ディレクトリを変更します)、同様にインクルードディレクトリに関連付けられている名前を削除(使用)します。find./this-execdirrmfchdir()-deleteunlinkat()

デフォルトでは(つまり、この-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から。

関連情報