数千のファイルに対するchmod再帰的許可


16

これは、「chmoding」に関する再帰的な一般的な質問です。

このスクリプトは、数十万個のファイルがあるフォルダーで、ある時点で再帰的にアクセス許可を変更する必要があるスクリプトです。そのフォルダーには毎日新しいファイルが追加されますが、既に存在するファイルには既にアクセス許可が設定されており、変更されません。

私の質問は...私が電話するときです

chmod 775。-R

すでに適切な権限が設定されているファイルに権限を設定しようとしていますか、または適切な権限が設定されていない新しいファイルにのみ権限を設定しようとしていますか?

「新しい」ファイルはほんの数千であり、許可をかなり迅速に行う必要がありますが、スクリプトでこのコマンドを通過するには常に時間がかかるようです。

chmodのマニュアルページを見ましたが、このケースについては何も言及していないようです。

chmodが事前に権限をチェックしない場合、「find」と「chmod」の組み合わせを検討する必要がありますか?


3
正しい値に直接設定するよりも、権限が正しくない場合、権限を確認して変更する方が本当に遅いのではないかと思います。
lgeorget

1
誰かがこれにつまずいてfind + chmodコマンドが必要な場合は、findです。!-perm 775 -print0 | xargs -0 -I {} chmod 775 {}
ティティドゥミ

@lgeorget、あなたはfind | chmodの使用が遅いと言っていますか?すべてをchmodするよりも。(ごめんなさい、あなたのコメントから理解できませんでした)。乾杯
ティティドゥミ

私の謙虚な意見では、2つのプロセスを処理し、最初のプロセスの出力を2番目のプロセスにリダイレクトする必要があるため、おそらく遅いですが、よくわかりません。iノードで変更するのはわずか3バイトであるため、それほど重要ではないかもしれないパーミッションの設定にかかる時間に依存します。
lgeorget

1
@depquidここでの主なパフォーマンスの問題は、データをディスクキャッシュに読み込むことです。最初の実行後、すべてがディスクキャッシュに格納されます(メモリが少なすぎる場合を除く)。したがって、実際の状況ではボトルネックではない何かのパフォーマンスをテストしています。
Hauke Laging

回答:


9

chmod既に希望するものに設定されているファイルのアクセス許可を変更する場合も変更しない場合もありますが、そうでない場合は、ファイルをチェックして現在のアクセス許可を確認する必要があります[0]。何十万ものファイルがあるので、どちらの方法でも問題になるとは思いません。ほとんどの場合、statすべてのファイルを作成するツールによって時間が費やされています。

あなたは使用して試すことができますfind必要があること最後の実行やファイルより新しいファイル用のいずれかのチェックをchmod実行することが、私はあなたが多くの速度向上を得るだろうとは思いません。

スクリプトで可能な場合は、最初に新しいファイルを「保持」領域として別のディレクトリに配置できる場合があります。次に、chmodTHATディレクトリ(新しいファイルのみ)を作成mvし、残りのファイルを追加します。これは大幅に高速になりますが、残念ながらすべてのアプリケーションで機能するとは限りません。

[0]変更を必要としないファイルの許可を設定しようとしても、基本となるファイルシステムは不要なので、おそらくリクエストに対して何もしません。


ありがとう。見つけてみます| chmodバージョンを使用して、高速化するかどうかを確認します。そうでない場合、私はあなたが提案したように「保持」フォルダを実装するためにスクリプトを変更しようとします。
ティティドゥミ

速度が向上しないのは、ctimeとアクセス権の両方でiノードを読み取る必要があるためです。
ハウケレイジング

10

find / chmod最適化

両方findchmodも読まなければならない

  1. すべてのディレクトリエントリ
  2. これらすべてのエントリのiノード

ディスクヘッドがディレクトリとiノード間を移動しないため、最初にすべてのエントリを読み取り、次にすべてのiノード(回転ディスク上)を読み取ると、おそらくパフォーマンスが向上します。以下のようchmod である愚かな(他の回答の一つが説明するように)それが通過呼ばれるべきfindのみ。しかし、それでも、最初のiノードが書き込まれる前にすべてのiノードを読み取ると役立つ場合があります(ディスクキャッシュに十分な空きRAMがあると仮定)。これをお勧めします:

find . -printf "" # reading the file names only
find . ! -perm 775 -printf "" # reading all the inodes (file names are cached)
find . ! -perm 775 -exec chmod 775 + # writing to the cache without reading from disk

良い解決策:ACL

良い解決策は完全に異なる可能性があります。ファイルがこのディレクトリに作成されている(そして他の場所から移動されていない)場合、ACLはその場でジョブを実行できます。親ディレクトリにデフォルトACLを設定するだけです。

ファイルシステムの最適化により、さらに改善される可能性があります。ext3 / ext4の場合e2fsck -D、時々実行できます。このディレクトリを別のボリュームに配置すると役立つ場合があります。異なるファイルシステムまたはファイルシステム設定(異なるiノードサイズなど)を試すことができます。


NFSv4マウントで作業していない限り、ACLは有効です。
-ostrokach

find溶液は、約、私の時間を倍増chmodドッキングウィンドウコンテナ内INGの。
ネイサンReinstateMonicaアーサー

8

使用と仮定chmodからのGNU coreutilsのパッケージのUbuntu 12.10上を。

chmod 775 . -Rfchmodat許可の変更が必要かどうかに関係なく、見つかったファイルごとにシステムコールを実行します。これを確認するには、コードを調べstrace chmod 775 . -R、実際の動作をリストするために(以下のスニペット)を使用します。

newfstatat(4, "d", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "d", 0775)                  = 0
newfstatat(4, "c", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "c", 0775)                  = 0
newfstatat(4, "a", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "a", 0775)                  = 0
newfstatat(4, "b", {st_mode=S_IFREG|0666, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat(4, "b", 0775)                  = 0

fchmodat各ファイルで実行することにはいくつかの欠点があります

  • 多数のファイルが変更された場合、余分なシステムコールが重要になる可能性があります。find/ xargs/ chmod他の人が言及した方法は、おそらく唯一の変更が必要なファイルを変更することにより、迅速になります。
  • の呼び出しfchmodatは、各ファイルのファイル状態の変更(ctime)を変更します。これにより、すべてのファイル/ inodeが毎回変更され、過剰なディスク書き込みが発生する可能性があります。マウントオプションを使用して、これらの過剰な書き込みを停止することができます。

単純な実験では、ctimeの変化がストレートで発生していることが示されています chmod

auser@duncow:/tmp/blah.test$ ls -lc
total 0
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 a
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 b
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 c
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:17 d
auser@duncow:/tmp/blah.test$ chmod 775 . -R
auser@duncow:/tmp/blah.test$ ls -lc
total 0
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 a
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 b
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 c
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 d

しかし、これはfind/ xargs/ chmod数分後には変わりません

auser@duncow:/tmp/blah.test$ date
Tue Jun 18 18:27:27 BST 2013
auser@duncow:/tmp/blah.test$ find . ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {}
auser@duncow:/tmp/blah.test$ ls -lc
total 0
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 a
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 b
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 c
-rwxrwxr-x 1 laptop laptop 0 Jun 18 18:25 d

find では、物の選択をより細かく制御できるため、常にfind/ xargs/ chmodバージョンを使用する傾向があります。


1

[ソース](1)は、chmod(1)常にモードの設定を試みてから、[fstatat(2)](2)で再度確認することを示しています。

ファイルは[fts(3)](3)を介して処理されます。これは、データツリーを構築するために、事前にすべてのトラバースされたファイルシステムオブジェクトを 'stat'する必要があります。

Unixloreの特徴は、[素晴らしい記事](4)でchmod(1)find/ xargsアプローチに対してタイミングがとられています。後者は大きさで勝ちます。

ここで、元の質問に適応したコマンドライン:

find . -print0 | xargs -0 chmod 775

2つの理由:

  1. ファイルシステムトラバーサルは、異なるコアで実行される可能性のある2つのプロセス間のパイプを介して、ファイルの操作から切り離されます。

    1. fts(3)xargs(1)ディレクトリツリーが「フラット化」されるため、操作が最小化されます。

はい:必ずfind/を使用する必要がありますxargs。シンプルなソリューション。

他のオプション:

  • [umask](5)および新しいファイルを書き込むプロセスのソースコードで遊んでください。

  • Linuxを使用している場合、システムがinotifyカーネルサブシステムを有効にしている可能性があります 。この場合、[inotifywait(1)](6)を使用して効率的なソリューションをスクリプト化できます。


補足:ファイルの実行権限が必要な場合を除き、呼び出しを次のように変更することをお勧めします。

find . -type f -print0 | xargs -0 chmod 664
find . -type d -print0 | xargs -0 chmod 775

編集者への注意:投稿に2つ以上のリンクを追加したり、他の投稿にコメントしたりすることはできません。ここにURLを残し、十分な評判のある率直なユーザーがそれらをテキストに戻し、この段落を削除することを願っています。


コメントディスクキャッシュをプライミングfind . -printf ""

これにより、次のchmod操作の実行が高速化される場合がありますが、使用可能なメモリとI / O負荷によって異なります。そのため、動作する場合と動作しない場合があります。トラバーサル(find)とchmod操作の分離により、キャッシュが既に提供されるため、キャッシュのプライミングは不要になる場合があります。

  1. https + lingrok.org / xref / coreutils / src / chmod.c#process_file
  2. https + linux.die.net / man / 2 / fstatat
  3. https + linux.die.net / man / 3 / fts
  4. http + www.unixlore.net / articles / speeding-up-bulk-file-operations.html
  5. https + en.wikipedia.org / wiki / Umask
  6. https + linux.die.net / man / 1 / inotifywait

0

ファイルを作成するプロセスを0775モードで作成するように変更することを検討しましたか?環境内のumask値を確認してください-0002が役立つ場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.