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 find
4.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}'