web-dev-qa-db-ja.com

Linux ext4での不正なバックアップ/復元後のファイルとディレクトリのアクセス権の復元

個人用ディレクトリのバックアップをrsyncで台無しにした(NTFSファイルシステムでバックアップしている可能性があるため):すべてのファイルはここにありますが、すべてのファイルとディレクトリのアクセス権は777です。再帰的に変更されるmagicユーティリティでした:

  • 777から755までのディレクトリ。
  • 777から644までの通常のファイルです。家には実行可能ファイルがあまりないので、後で手作業で管理できます。
  • 他のファイル(リンク、他に何か?)は変更しないでください。

シェルで行うのは簡単ですが、何時間もかかります...

副次的な質問:NTFSでLinuxディレクトリ階層を適切にバックアップするためのアドバイス(rsyncor other)。

10
mszmurlo

標準的な推奨ソリューションは簡単です。

find . -type d -exec chmod 0755 "{}" \+
find . -type f -exec chmod 0644 "{}" \+

これにより、システムの最大コマンド行長まで、単一のコマンドに可能な限り多くのファイル名を引数として追加します。行がこの長さを超える場合、コマンドは複数回呼び出されます。

ファイルごとに1回コマンドを呼び出す場合は、代わりに次のように実行できます。

find . -type d -exec chmod 0755 "{}" \;
find . -type f -exec chmod 0644 "{}" \;
16
harrymc

_chmod -R a=,u+rwX,go+rX $DIR_は正常に動作するようで、最も高速である可能性が非常に高いですが、それを見てください。

(私はstraceでチェックしましたが、ファイル/ディレクトリごとにonefchmodat() syscallのみを作成します-644のファイルと755のディレクトリの場合)。

コツは、_Xパーミッションで、_man chmod_に文書化されています。これは、ディレクトリに対してのみxのように機能します。

notと記載されているのは、それらが指定されたのと同じ順序で適用され、ランダムな順序だけでなく、複数のバリアントで繰り返しテストを行った結果、実際に実行されると確信していることです。与えられた順番で、私はこれが常にこのように機能するだろうと確信しています。

これはLinuxに関するものですが、chmodのBSDマンページをざっと読むと、-すべきでも機能することが示唆されています。

15
sitaram

私は sitaramの回答Peter CordesのコメントFanatiqueの回答 、および harrymcの回答 をベンチマークしましたが、この答えは最も速い方法です

平均:

  • Deltikの答え* – 7.480秒
    * Peter Cordes の功績 Suggesting parallelism
  • sitaramの回答– 12.962秒(最高より73.275%遅い)
  • Peter Cordesのコメント– 14.414秒(最高より92.685%遅い)
  • Fanatiqueの答え– 14.570秒(最高より94.772%遅い)
  • harrymcの最新の回答– 14.791秒(最高より97.730%遅い)
  • harrymcの元の回答– 1061.926秒(14096.113%が最高より遅い)

完全な統計サマリー:

_Author              N      min     q1      median  q3      max     mean    stddev
------------------  --     ------- ------- ------- ------- ------- ------- --------
Deltik              10     7.121   7.3585  7.4615  7.558   8.005   7.4804  0.248965
sitaram             10     12.651  12.803  12.943  13.0685 13.586  12.9617 0.276589
Peter Cordes        10     14.096  14.2875 14.375  14.4495 15.101  14.4136 0.269732
Fanatique           10     14.219  14.512  14.5615 14.6525 14.892  14.5697 0.211788
harrymc (updated)   10     14.38   14.677  14.8595 14.9025 15.119  14.791  0.21817
harrymc (original)  1      1061.93 1061.93 1061.93 1061.93 1061.93 1061.93 N/A
_

Deltikのコマンド、ベンチマーク形式:

find "$(pwd)" -type d | xargs -P4 chmod 755&\ 
 find "$(pwd)" -type f | xargs -P4 chmod 644&wait

ベンチマーク形式のsitaramのコマンド:

 chmod -R a =、u + rwX、go + rX "$(pwd)" 

ベンチマーク形式のPeter Cordesのコマンド:

 find "$(pwd)" \(-type d -exec chmod 755 {} + \)\ 
 -o \(-type f -exec chmod 644 {} + \)

ベンチマーク形式のFanatiqueのコマンド:

 find "$(pwd)" -type d -print0 | xargs -0 chmod 755;\
 find "$(pwd)" -type f -print0 | xargs -0 chmod 644 

ベンチマーク形式のharrymcの更新されたコマンド:

 find "$(pwd)" -type d -exec chmod 755 {} +;\
 find "$(pwd)" -type f -exec chmod 644 {} + 

ベンチマーク形式のharrymcの元のコマンド:

 find "$(pwd)" -type d -exec chmod 755 {} \; ;\
 find "$(pwd)" -type f -exec chmod 644 {} \; 

ファイルタイプごとに4つの並列chmodプロセスがあるため、私のコマンドは最速でした。これにより、複数のCPUコアがchmodを実行できるようになり、ボトルネックがカーネルI/Oスレッドまたはディスクに移動しました。

すべてがchmodコマンド内で行われるため、sitaramのコマンドは2位でした。これにより、他の回答と比較してオーバーヘッドが大幅に削減されます。

  • ファイルをスキャンする必要があるのは1回だけです(2つではなく1つのfindを実行するのと同様)。
  • 子プロセスを作成する必要はありません。

ただし、このコマンドは、通常のファイルとディレクトリの間で実行可能ビットの異なる意味を含むトリックに依存しているため、最も柔軟性がありません。

1つのfindコマンドを使用するPeter Cordesのコメントは、ディレクトリエントリの二重検索を防ぎます。ファイルの数が多いほど、この改善は大きくなります。それでも子chmodプロセスを作成するオーバーヘッドがあるため、chmodのみのソリューションよりもかなり低速です。

Fanatiqueのコマンドとharrymcの更新されたコマンドの間で、findにパイプされたxargs(_find | xargs_)は、結果のストリームが非同期で処理されるため、より高速でした。 _-exec_の検索動作をfindで一時停止する代わりに、検索結果はxargsに送信されて並行処理されます。
(nullバイト区切り文字(_find -print0 | xargs -0_)は実行時間に影響を与えなかったようです。)

harrymcの元のコマンドは、すべてのファイルとフォルダーごとに新しいchmodコマンドのオーバーヘッドがあり、それぞれが順番に実行されたため、遅すぎました。


テストセットアップでは、1001のディレクトリに1000002の通常ファイルが含まれていました。

 root @ demo:〜#echo {0..999} | xargs mkdir -p 
 root @ demo:〜#find -type d -exec bash -c "cd {}; echo {0..999} | xargs touch" \; 
 root @ demo :〜#検索| wc -l 
 1001003 
 root @ demo:〜#find -type d | wc -l 
 1001 
 root @ demo:〜#find -type f | wc -l 
 1000002 

質問の初期条件のように、すべてのファイルとフォルダーに_777_権限を設定しました。

次に、テストを実行する前に、chmod -R 0777 "$(pwd)"を使用して_777_へのアクセス許可を復元するたびに、コマンドを10回ベンチマークしました。

各ベンチマークコマンドの出力を含むファイルを表すOUTPUTを使用して、以下を使用して平均時間を計算しました。

_bc <<< "scale=3; ($(grep real OUTPUT | grep -Po '(?<=m).*(?=s)' | xargs | sed 's/ /+/g'))/10"
_

Deltikの回答のベンチマークの結果

 root @ demo:〜#for i in {0..9}; chmod -R 0777 "$(pwd)"を実行します。時間{find "$(pwd)" -type d | xargs -P4 chmod 755& "$(pwd)" -type f |を検索xargs -P4 chmod 644&wait; };完了
 [1] 9791 
 [2] 9793 
 [1]-完了 "$(pwd)" -type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m7.634s 
 user 0m2.536s 
 sys 0m23.384s 
 [1] 9906 
 [2] 9908 
 [1]-「$(pwd)」を見つけました-type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m7.443s 
 user 0m2.636s 
 sys 0m23.106s 
 [1] 10021 
 [2] 10023 
 [1]-「$(pwd)」を見つけました-type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m8.005s 
 user 0m2.672s 
 sys 0m24.557s 
 [1] 10136 
 [2] 10138 
 [1]-「$(pwd)」を見つけました-type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m7.480s 
 user 0m2.541s 
 sys 0m23.699s 
 [1] 10251 
 [2] 10253 
 [1]-「$(pwd)」を見つけました-type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m7.397s 
 user 0m2.558s 
 sys 0m23.583s 
 [1] 10366 
 [2] 10368 
 [1]-「$(pwd)」を見つけました-type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m7.482s 
 user 0m2.601s 
 sys 0m23.728s 
 [1] 10481 
 [2] 10483 
 [1]-「$(pwd)」を見つけました-type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m7.679s 
 user 0m2.749s 
 sys 0m23.395s 
 [1] 10596 
 [2] 10598 
 [1]-完了 "$(pwd)" -type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m7.243s 
 user 0m2.583s 
 sys 0m23.400s 
 [1] 10729 
 [2] 10731 
 [1]-「$(pwd)」を見つけました-type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m7.320s 
 user 0m2.640s 
 sys 0m23.403s 
 [1] 10844 
 [2] 10847 
 [1]-完了 "$(pwd)" -type d | xargs -P4 chmod 755 
 [2] + Done find "$(pwd)" -type f | xargs -P4 chmod 644 
 
 real 0m7.121s 
 user 0m2.490s 
 sys 0m22.943s 

平均時間:7.480秒

Sitaramの回答のベンチマークの結果

 root @ demo:〜#for i in {0..9}; chmod -R 0777 "$(pwd)"を実行します。時間chmod -R a =、u + rwX、go + rX "$(pwd)";完了
 
実際0m12.860s 
ユーザー0m0.940s 
 sys 0m11.725s 
 
実際0m13.059s 
 user 0m0.896s 
 sys 0m11.937s 
 
 real 0m12.819s 
 user 0m0.945s 
 sys 0m11.706s 
 
実際0m13.078s 
ユーザー0m0.855s 
 sys 0m12.000s 
 
実際0m12.653s 
ユーザー0m0 .856s 
 sys 0m11.667s 
 
実際の0m12.787s 
ユーザー0m0.820s 
 sys 0m11.834s 
 
実際の0m12.651s 
ユーザー0m0.916s 
 sys 0m11.578s 
 
実際の0m13.098s 
ユーザー0m0.939s 
 sys 0m12.004s 
 
 real 0m13.586s 
 user 0m1.024s 
 sys 0m12.372s 
 
 real 0m13.026s 
ユーザー0m0.976s 
 sys 0m11.910s 

平均時間:12.962秒

Peter Cordesのコメントのベンチマークの結果

 root @ demo:〜#for i in {0..9}; chmod -R 0777 "$(pwd)"を実行します。 time find "$(pwd)" \(-type d -exec chmod 755 {} + \)-o \(-type f -exec chmod 644 {} + \);完了
 
実際0m14.096s 
ユーザー0m1.455s 
 sys 0m12.456s 
 
実際0m14.492s 
 user 0m1.398s 
 sys 0m12.897s 
 
 real 0m14.309s 
 user 0m1.518s 
 sys 0m12.576s 
 
リアル0m14.451s 
ユーザー0m1.477s 
 sys 0m12.776s 
 
リアル0m15.101s 
ユーザー0m1 .554s 
 sys 0m13.378s 
 
 real 0m14.223s 
 user 0m1.470s 
 sys 0m12.560s 
 
実際の0m14.266s 
ユーザー0m1.459s 
 sys 0m12.609s 
 
実際の0m14.357s 
ユーザー0m1.415s 
 sys 0m12.733s 
 
 real 0m14.393s 
 user 0m1.404s 
 sys 0m12.830s 
 
 real 0m14.448s 
ユーザー0m1.492s 
 sys 0m12.717s 

平均時間:14.414秒

Fanatiqueの回答のベンチマークの結果

 root @ demo:〜#for i in {0..9}; chmod -R 0777 "$(pwd)"を実行します。時間{find "$(pwd)" -type d -print0 | xargs -0 chmod 755; 「$(pwd)」を検索-type f -print0 | xargs -0 chmod 644; };完了
 
実際0m14.561s 
ユーザー0m1.991s 
 sys 0m13.343s 
 
実際0m14.521s 
 user 0m1.958s 
 sys 0m13.352s 
 
 real 0m14.696s 
 user 0m1.967s 
 sys 0m13.463s 
 
リアル0m14.562s 
ユーザー0m1.875s 
 sys 0m13.400s 
 
リアル0m14.609s 
ユーザー0m1 .841s 
 sys 0m13.533s 
 
実際の0m14.892s 
 user 0m2.050s 
 sys 0m13.630s 
 
実際の0m14.291s 
ユーザー0m1.885s 
 sys 0m13.182s 
 
実際の0m14.843s 
ユーザー0m2.066s 
 sys 0m13.578s 
 
 real 0m14.219s 
 user 0m1.837s 
 sys 0m13.145s 
 
 real 0m14.503s 
ユーザー0m1.803s 
 sys 0m13.419s 

平均時間:14.570秒

Harrymcの更新された回答のベンチマークの結果

 root @ demo:〜#for i in {0..9}; chmod -R 0777 "$(pwd)"を実行します。 time {find "$(pwd)" -type d -exec chmod 755 {} +; 「$(pwd)」を検索-type f -exec chmod 644 {} +; };完了
 
実際0m14.975s 
ユーザー0m1.728s 
 sys 0m13.050s 
 
実際0m14.710s 
 user 0m1.586s 
 sys 0m12.979s 
 
 real 0m14.644s 
 user 0m1.641s 
 sys 0m12.872s 
 
実際の0m14.927s 
ユーザー0m1.706s 
 sys 0m13.036s 
 
実際の0m14.867s 
ユーザー0m1 .597s 
 sys 0m13.086s 
 
 real 0m15.119s 
 user 0m1.666s 
 sys 0m13.259s 
 
実際の0m14.878s 
ユーザー0m1.590s 
 sys 0m13.098s 
 
実際の0m14.852s 
ユーザー0m1.681s 
 sys 0m13.045s 
 
 real 0m14.380s 
 user 0m1.603s 
 sys 0m12.663s 
 
 real 0m14.558s 
ユーザー0m1.514s 
 sys 0m12.899s 

平均時間:14.791秒

ハリーマックの元の回答のベンチマークの結果

このコマンドの速度が遅いため、ベンチマークを1回だけ実行しました。

 root @ demo:〜#for i in {0..0}; chmod -R 0777 "$(pwd)"を実行します。 time {find "$(pwd)" -type d -exec chmod 755 {} \; ; 「$(pwd)」を検索-type f -exec chmod 644 {} \; ; };完了
 
実際の17m41.926s 
ユーザー12m26.896s 
 sys 4m58.332s 

所要時間:1061.926秒

10
Deltik

ディレクトリが大きすぎてファイルが多すぎる場合、@ harrymcが示した元の方法は失敗します。

ファイルが多すぎる場合は、findxargschmodでパイプする必要があります。

find /base/dir -type d -print0 | xargs -0 chmod 755 
find /base/dir -type f -print0 | xargs -0 chmod 644
3
Fanatique