他のユーザーがディレクトリに何も所有していない場合は、そのユーザーが所有する最上位ディレクトリを返します。

他のユーザーがディレクトリに何も所有していない場合は、そのユーザーが所有する最上位ディレクトリを返します。

次のディレクトリ構造と所有権を使用します。

userA ./dir1          
userA ./dir1/dir1.1
userA ./dir1/dir1.2
userA ./dir2
userA ./dir2/dir2.1
userA ./dir2/dir2.1/dir2.1.1
userB ./dir2/dir2.2
userB ./dir3

実行すると、find . -type d -user userA以下が返されます。

./dir1          
./dir1/dir1.1
./dir1/dir1.2
./dir2
./dir2/dir2.1
./dir2/dir2.1/dir2.1.1

しかし、私はこの出力を見たいです。

./dir1
./dir2/dir2.1
  • dir1.1dir1.2他のユーザーがそれを所有していないため、返されませんdir1
  • 同様にdir2.1.1返品もありません。
  • dir2userBに属しているため(userAに属していても)返されませんdir2.2

これは、ユーザーが実行するために「安全な」ディレクトリを識別できるようにディスクをクリーンアップするのに役立ちますrm -rf。何十億ものファイルがある場合、duランタイムは非常に高いです。また、ディレクトリがすべての階層レベルにある可能性があるため、検索の深さを制限することは役に立ちません。

答え1

次のスクリプトを使用してください。

#!/bin/sh -

u="$1"
shift

find "$@" -type d -user "$u" ! -exec sh -c '
   find "$2" -type d ! -user "$1" | grep -qm 1 .
' find-sh "$u" {} \; -prune -print

使用例:

/path/to/the_script userA ./

最初のパラメータ(ここではuserA)はユーザー名です。以下のすべて(ここ./)はに渡されますfind。開始経路はこの方法で渡す必要があります(技術的には注入は可能ですが)。

スクリプトはmainを使用して、findユーザーが所有するディレクトリを見つけます。これらのディレクトリの場合、findユーザーに属さないサブディレクトリを探す他のディレクトリが呼び出されます。そうでない場合は、ディレクトリを削除し(したがってmainはfind子ディレクトリを解決しません)、そのパス名を印刷します。

メモ:

  • 内部的にfind何かが見つかると、外部(デフォルト)findはディレクトリをクリーンアップせずに代わりにサブディレクトリをチェックします。内部で見つかった内容が深い場合は、findスクリプトがディレクトリツリーの別のブランチに移動する前に、さまざまなレベルの多くのサブディレクトリを何度も「無駄に」チェックします。ディレクトリツリーが非常に大きくない限り、オペレーティングシステムはメタデータをキャッシュする必要があり、次に同じサブディレクトリをfind調べるときは速くなければなりません。何度もチェックするのは最適ではないように見えるかもしれませんが、これを最適化しようとするとコードが複雑になるため、それほど価値がありません。
  • grep -m 1最初の一致後に終了しますが、このオプションは移植可能ではありません。grepサポートしていない場合は使用-mしないでください(つまり、使用してくださいgrep -q .)。スクリプトは遅くなりますが、動作します。
  • find-sh説明は次のとおりです。の2番目のshは何ですかsh -c 'some shell code' sh
  • タイトルには「他のユーザーが何も所有していない場合」と呼ばれていますが、例とユースケースには「他のユーザーがサブディレクトリを所有していない場合」と記載されています。私のスクリプトは(サブ)ディレクトリのみをチェックします。 「そうでない場合...」を確認するには、-type d内部呼び出しのテストを無視してくださいfind
  • Permission deniedエラーは誤った肯定を引き起こす可能性があります。

関連情報