検索:削除が許可されているファイルのみを削除

検索:削除が許可されているファイルのみを削除

find特定の基準に一致するファイルを削除するために使用する方法:

find -type f [more criteria] -delete

通常、これはうまくいきますが、他のユーザーが作成したサブディレクトリに問題があります。私が知っている限り、そのユーザーはファイルの削除を許可しますか?親ディレクトリに対する私の権限によって異なります。。したがって、他のユーザーが作成したサブディレクトリに含まれるファイルに対しては、上記のコマンドは失敗します。

fbrucker@host /tmp $ ls -lh
total 4,0K
drwxrwxr-x 2 root root 4,0K Jun 15 11:44 foo/

fbrucker@host /tmp $ ls -lh foo/
total 0
-rw-rw-r-- 1 fbrucker fbrucker 0 Jun 15 11:44 a
-rw-rw-r-- 1 root     root     0 Jun 15 11:44 b

fbrucker@host /tmp $ find -type f -delete
find: cannot delete ‘./foo/b’: Permission denied
find: cannot delete ‘./foo/a’: Permission denied

大丈夫です。ファイルを削除することはできませんが、権限が不足するとfindゼロ以外の状態で終了します。私はこのような状況を避けたい。

削除できないファイルを削除する前にどのようにフィルタリングできますか?

エラーメッセージをフィルタリングするだけです。いいえまだゼロ以外の終了コードが残っているので、これで十分です。また、終了コードを完全に無視することは他のエラーをキャッチしたいので動作しません(実際のコマンドfindはより複雑です。find /somedir -type f -deleteいいえ/somedir存在しない場合に発生するエラーは無視されます。)

findファイル(例えば、、、)に対する権限をテストすることを知っていますが、ここ-permには適用されないようです。例えば、-readable-writable

fbrucker@host /tmp $ find -type f -writable
./foo/a

foo/a必要な権限がないため削除できませんfoo

-deletableテストのようなものを探していますが、存在しないようです。

ベストアンサー1

はい、親ディレクトリへの書き込み権限が必要で、そのディレクトリにビットが設定されている場合は、リンクを解除したいtディレクトリまたはファイルの所有者である必要があります。これはすべてACLなどの他のセキュリティ制御がなく、ファイルが配置されているFSは読み取り専用ではないため取り外し可能検査はより複雑です。

for -readable// -writable(-executable非標準) 対応するfindシステムaccess(R_OK/W_OK/X_OK)コールを使用できますが、対応するものはありません。解く1つの文書。

GNU find4.9.0以降では、次のように近似できます。

find . -depth -type d -writable '(' -uid "$EUID" -o ! -perm -o=t ')' -print0 |
  find -files0-from - -mindepth 1 -maxdepth 1 -type f -delete

zsh(またはなどのbashシェル設定を想定します$EUID。そうでない場合はそれを使用してください"$(id -u)")。

これにより、所有ファイルが所有していない-bitディレクトリに残り、tそのファイルを別々に処理する必要があります。

find . -depth -type d -writable ! -uid "$EUID" -perm -o=t -print0 |
  find -files0-from - -mindepth 1 -maxdepth 1 -type f -uid "$EUID" -delete

pipefail最初のfind

以前のバージョンのGNUでは、findいつでも次のことができます。

find . -depth -type d -writable '(' -uid "$EUID" -o ! -perm -o=t ')' -exec sh -c '
  exec find "$@" -mindepth 1 -maxdepth 1 -type f -delete
  ' sh {} +

アクセス権によるファイルのリンク解除の失敗を無視することが重要な場合は、次のようにできます。

set -o pipefail
find . -depth -type f -print0 |
  perl -l -0ne '
    unless (unlink($_) || $!{EACCES}) {
      warn "$_: $!\n";
      $ret = 1;
    }
    END {exit $ret}'

おすすめ記事