- 締切済み
find . -user hoge の代わりに。。
/home 以下で ユーザー hoge の全ファイルを抽出するのに、 find /home -user hoge としていますが、とても遅く、そして何よりも、負荷が高くなりすぎます。 毎日実行する必要があり、他に同様のことを実現するベターな方法はないでしょうか。 locate はファイル名を検索するだけで、「ユーザー hoge を探す」方法が ないように思います。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- hanabutako
- ベストアンサー率54% (492/895)
「userがroot になっているファイルを毎日検索したいです」というセキュリティ用途っぽい感じなら、auditが使えるのではないかと思います。 auditはfindのように網羅的に今の状態を調べることはできませんが、ルールに合致したシステムコールを記録することができます。つまり、おそらくはrootが所有者となっているファイルが作られた場合 (uid=0のユーザーによるcreatシステムコールなど)、rootにchownされた場合(所有者をuid 0にするchownシステムコールなど)を記録に残すようにできます。 あるいは、SELinuxの機能を利用して、rootユーザーのファイルの作成を禁止することもできると思います。 auditはfindと違って、今の状態はわかりませんが、一度findしてからauditで監視しておけば、findした時からの差分とあわあせて、現在rootが所有しているファイルがわかるようになると思います。 所定のシステムコールの発行のたびにチェックされるのでその分遅くなりますが、あまり頻繁にファイルの作成はchownはしないと思うので、こちらのほうが総合的な負荷は低いかもしれません。
- notnot
- ベストアンサー率47% (4900/10358)
No1です。 >とたくさんユーザーとファイルがある中で、userがroot になっているファイルを毎日検索したいです。 となると、find以上に速い物はなさそうです。 速くなるかどうかわかりませんが、更新のファイルディレクトリが少ないのであれば、最近更新の掛かったディレクトリだけに限定するというのも考えられます。 find `find /home -type d -mtime -2 ` -maxdepth 1 -user root ただし、これではroot所有の全部は検出できません。最近作られた物を含む一部だけです。昨日分と比較することで増えた物がわかるはず。
お礼
最近の更新ディレクトリーだけに絞る最初のfindの時点で同じように負荷が大きくなり、 結局、過去のデータから当たりをつけて検索対象ディレクトリーを最初から絞り込むことにしました。 全部をすくい取ることはできそうもありませんが当面はこの運用でいくしかないと思いました。 ありがとございました。
- hanabutako
- ベストアンサー率54% (492/895)
#1さんの回答に補足ですが、 特定のディレクトリーにしかユーザーのファイルがないとわかっているなら、locateでディレクトリーを絞り込んで、探す範囲を限定してから、statでユーザーを絞り込むのがいいと思います。 例えば、ホームディレクトリーなどそのユーザーの名前がついたディレクトリーからそのユーザーのファイルを探してくるならこういう方法もあるかと。 locate $USER | xargs stat -f "%Su %SN" | egrep "^$USER" | awk '{print $2}' fork+execのオーバヘッドを考えると、パイプでつないでプログラムを書くよりもPerlなどで全部書いたほうが多分速いんですけどね。 この手のシステムスクリプトを高速化する場合の基本方針は次の4つだと思います。 a. 早めに枝刈りをする。参照するデータを絞り込む。 (加工する必要があるデータに絞り込んでから加工) b. なるべく一箇所にまとまったデータを使う (新鮮な情報が必要でないなら、findよりはlocate) c. システムコールを呼ぶ回数を減らす (シェルクリプトではなく、Perlスクリプト) d. キャッシュを有効活用する このスクリプトの実際の運用を知れば、find /home -user hogeだけを見せられるよりもまだ改善の余地はありそうです。 1. /home全体にuserのデータが存在し得るのか?特定のところにあるという事はないのか? あるいは、/home/userにないuserのデータを探したいなら、/home/userを除いて探せないか? (方針a) 2. 毎日実行するほど頻繁にuserのデータは書き換わるのか? 例えば、持ち主の変更を考慮しないで良いなら、ファイル名と持ち主の情報が入ったBerkeley DBを作り、そこにデータをキャッシュできないか? (方針d) 3. このスクリプトでは一人のユーザーの情報しか探さないのか? もし、findを複数のユーザーに対して行うなら、初回でDBを作り、あとはそのDBを参照するだけにできないか? (方針b、d) 4. find ...は単体で呼び出すのか、スクリプトから呼び出すのか スクリプトから呼び出すなら、そのスクリプトをPerlなどで書きなおして外部のコマンドを呼ぶ回数をを減らせないか。(かつてはpythonやrubyなどよりもperlが高速でしたが、今は違うかもしれません) (方針c) というわけで、findが呼ばれる背景がわかると枝刈りももっと効率的に出来るように思います。あとは上記方針を参考に書き換えてみてください。
補足
#1さんのおっしゃるようにコマンド一発の方法は無いのですね。find /home/hoge ではだめで、 ちょっと質問が間違っていまして正確には /home/aaa /home/bbb /home/ccc /home/ ..... とたくさんユーザーとファイルがある中で、userがroot になっているファイルを毎日検索したいです。 そういったファイルはランダムな場所にランダムに発生しますので 以下をcron で単純に実行して書き出していますが、 find /home -user root > hoge.txt 負荷的に厳しく代替手段に苦慮しています。
- notnot
- ベストアンサー率47% (4900/10358)
ファイルの所有ユーザを調べるためには実際にそれぞれのファイルのinodeをアクセスする必要があるために、findより抜本的に速い方法というのは無いです。 find /home/hoge じゃ駄目なんですか?
お礼
そういう方法もあるんですね。auditの記述の仕方から勉強してみます。