Linux ext4 は、バックアップ/復元が失敗した後にファイルとディレクトリのアクセス権を復元します。

Linux ext4 は、バックアップ/復元が失敗した後にファイルとディレクトリのアクセス権を復元します。

個人ディレクトリのバックアップを台無しにしてしまったrsync(おそらくNTFSファイルシステムでバックアップしているからだろう): すべてのファイルはここにあるが、すべてのファイルとディレクトリのアクセス権が777になっている。魔法再帰的に変更するユーティリティ:

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

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

補足的な質問: NTFS (またはその他の方法) 上の Linux ディレクトリ階層を適切にバックアップするためのアドバイスはありますかrsync

答え1

標準的に推奨される解決策は簡単です。

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 "{}" \;

答え2

chmod -R a=,u+rwX,go+rX $DIRうまく動作しているようで、どう見てもこれが最速である可能性が高いです。

(私は で確認しましたstraceが、1つ fchmodat()ファイル/ディレクトリごとのシステム コール (ファイルの場合は 644、ディレクトリの場合は 755)。

秘訣はX、 に記載されているman chmodxディレクトリに対してのみ のように動作する権限です。まさにこれが、あなたが望んでいた区別です。

とはない文書化されているのは、それらが指定されたのと同じ順序で適用され、ランダムな順序で適用されるわけではないという私の推測ですが、いくつかのバリエーションで繰り返しテストした結果、それらは確かに指定された順序で実行されることがわかったので、これが常にこのように機能すると確信しています。

これはLinux上でのことだということを述べておくべきだろうが、BSDのマニュアルページchmodをざっと読むと、すべきそこでも働きます。

答え3

私はベンチマークしたシタラムの答えピーター・コーデスのコメントファナティックの答え、 そしてharrymc の回答、 しかしこの答えは最速の方法である

平均:

  • Deltikの回答* – 7.480秒
    * クレジットピーター・コーデスのために平行性を示唆する
  • sitaram の回答 – 12.962 秒 (最高より 73.275% 遅い)
  • ピーター・コーデスのコメント – 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 のコマンド (ベンチマーク形式):

「$(pwd)」を検索 -type d -print0 | xargs -0 -P4 chmod 755 & \
"$(pwd)" を検索 -type f -print0 | xargs -0 -P4 chmod 644 & wait

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

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

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

「$(pwd)」を検索 \( -type d -exec chmod 755 {} + \) \
           -o \( -type f -exec chmod 644 {} + \)

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

"$(pwd)" を検索 -type d -print0 | xargs -0 chmod 755 ; \
「$(pwd)」を検索 -type f -print0 | xargs -0 chmod 644

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

「$(pwd)」を検索 -type d -exec chmod 755 {} + ; \
「$(pwd)」を検索 -type f -exec chmod 644 {} +

harrymc のオリジナルコマンド(ベンチマーク形式):

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

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

sitaram のコマンドは、すべてがコマンド内で実行されるため、次点となりましたchmod。これにより、他の回答と比較してオーバーヘッドが大幅に削減されます。その理由は次のとおりです。

  • ファイルは一度スキャンするだけで済みます(find2回ではなく1回行うのと同様)。
  • 子プロセスを作成する必要はありません。

ただし、このコマンドは、通常のファイルとディレクトリ間の実行ビットの意味が異なるというトリックに依存しているため、柔軟性が最も低くなります。

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

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

chmodharrymc の元のコマンドは、各ファイルとフォルダーごとに新しいコマンドが順番に実行されるオーバーヘッドが原因で、非常に遅くなりました。


テスト設定では、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質問の初期条件のように、すべてのファイルとフォルダーに権限を設定しました。

次に、テストを実行する前777に権限を復元しながら、コマンドを 10 回ベンチマークしました。chmod -R 0777 "$(pwd)"

OUTPUT各ベンチマーク コマンドの出力を含むファイルを表し、次のように平均時間を計算しました。

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

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

root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time { find "$(pwd)" -type d -print0 | xargs -0 -P4 chmod 755 & find "$(pwd)" -type f -print0 | xargs -0 -P4 chmod 644 & wait ; } ; done
[1] 9791
[2] 9793
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分7秒634
ユーザー 0分2.536秒
システム 0分23秒384秒
[1] 9906
[2] 9908
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分7秒443
ユーザー 0分2.636秒
システム 0分23秒106秒
[1] 10021
[2] 10023
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分8秒005
ユーザー 0分2.672秒
システム 0分24秒557秒
[1] 10136
[2] 10138
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分7秒480
ユーザー 0分2.541秒
システム 0分23秒699秒
[1] 10251
[2] 10253
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分7秒397
ユーザー 0分2.558秒
システム 0分23秒583秒
[1] 10366
[2] 10368
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分7秒482
ユーザー 0分2.601秒
システム 0分23秒728秒
[1] 10481
[2] 10483
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分7秒679
ユーザー 0分2.749秒
システム 0分23秒395秒
[1] 10596
[2] 10598
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分7秒243
ユーザー 0分2.583秒
システム 0分23秒400秒
[1] 10729
[2] 10731
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分7秒320
ユーザー 0分2.640秒
システム 0分23秒403秒
[1] 10844
[2] 10847
[1]- 完了 find "$(pwd)" -type d | xargs -P4 chmod 755
[2]+ 完了 find "$(pwd)" -type f | xargs -P4 chmod 644

実数 0分7秒121
ユーザー 0分2.490秒
システム 0分22秒943秒

平均時間: 7.480秒

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

root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time chmod -R a=,u+rwX,go+rX "$(pwd)" ; 完了

実数 0分12秒860秒
ユーザー 0m0.940s
システム 0分11秒725秒

実数 0分13秒059
ユーザー 0分0.896秒
システム 0分11秒937秒

実数 0分12秒819
ユーザー 0分0.945秒
システム 0分11秒706秒

実数 0分13秒078
ユーザー 0分0.855秒
システム 0分12.000秒

実数 0分12秒653
ユーザー 0分0.856秒
システム 0分11.667秒

実数 0分12秒787
ユーザー 0m0.820s
システム 0分11秒834秒

実数 0分12秒651
ユーザー 0分0.916秒
システム 0分11秒578秒

実数 0分13秒098
ユーザー 0分0.939秒
システム 0分12秒004秒

実数 0分13秒586
ユーザー 0m1.024s
システム 0分12秒372秒

実数 0分13秒026
ユーザー 0m0.976s
システム 0分11秒910秒

平均時間: 12.962秒

ピーター・コーデスのコメントのベンチマーク結果

root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time find "$(pwd)" \( -type d -exec chmod 755 {} + \) -o \( -type f -exec chmod 644 {} + \) ; done

実数 0分14秒096
ユーザー 0分1.455秒
システム 0分12秒456秒

実数 0分14秒492
ユーザー 0分1.398秒
システム 0分12.897秒

実数 0分14秒309
ユーザー 0分1.518秒
システム 0分12.576秒

実数 0分14秒451
ユーザー 0分1.477秒
システム 0分12.776秒

実数 0分15秒101
ユーザー 0m1.554s
システム 0分13秒378秒

実数 0分14秒223
ユーザー 0m1.470s
システム 0分12.560秒

実数 0分14秒266
ユーザー 0分1.459秒
システム 0分12秒609秒

実数 0分14秒357
ユーザー 0分1.415秒
システム 0分12秒733秒

実数 0分14秒393
ユーザー 0m1.404s
システム 0分12秒830秒

実数 0分14秒448
ユーザー 0分1.492秒
システム 0分12秒717秒

平均時間: 14.414秒

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

root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time { find "$(pwd)" -type d -print0 | xargs -0 chmod 755 ; find "$(pwd)" -type f -print0 | xargs -0 chmod 644 ; } ; 完了

実数 0分14秒561
ユーザー 0m1.991s
システム 0分13秒343秒

実数 0分14秒521
ユーザー 0分1.958秒
システム 0分13秒352秒

実数 0分14秒696
ユーザー 0m1.967s
システム 0分13秒463秒

実数 0分14秒562
ユーザー 0分1.875秒
システム 0分13秒400秒

実数 0分14秒609
ユーザー 0分1.841秒
システム 0分13秒533秒

実数 0分14秒892
ユーザー 0m2.050s
システム 0分13秒630秒

実数 0分14秒291
ユーザー 0分1.885秒
システム 0分13秒182秒

実数 0分14秒843
ユーザー 0分2.066秒
システム 0分13秒578秒

実数 0分14秒219
ユーザー 0分1.837秒
システム 0分13秒145秒

実数 0分14秒503
ユーザー 0分1.803秒
システム 0分13秒419秒

平均時間: 14.570秒

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

root@demo:~# for i in {0..9} ; do chmod -R 0777 "$(pwd)" ; time { find "$(pwd)" -type d -exec chmod 755 {} + ; find "$(pwd)" -type f -exec chmod 644 {} + ; } ; done

実数 0分14秒975
ユーザー 0分1.728秒
システム 0分13秒050秒

実数 0分14秒710秒
ユーザー 0分1.586秒
システム 0分12秒979秒

実数 0分14秒644
ユーザー 0m1.641s
システム 0分12.872秒

実数 0分14秒927
ユーザー 0m1.706s
システム 0分13秒036秒

実数 0分14秒867
ユーザー 0m1.597s
システム 0分13秒086秒

実数 0分15秒119
ユーザー 0分1.666秒
システム 0分13秒259秒

実数 0分14秒878
ユーザー 0m1.590s
システム 0分13秒098秒

実数 0分14秒852
ユーザー 0m1.681s
システム 0分13秒045秒

実数 0分14秒380秒
ユーザー 0分1.603秒
システム 0分12.663秒

実数 0分14秒558
ユーザー 0分1.514秒
システム 0分12秒899秒

平均時間: 14.791秒

harrymc の元の回答のベンチマークの結果

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

root@demo:~# for i in {0..0} ; do chmod -R 0777 "$(pwd)" ; time { find "$(pwd)" -type d -exec chmod 755 {} \; ; find "$(pwd)" -type f -exec chmod 644 {} \; ; } ; done
 
実数 17分41秒926
ユーザー 12分26秒896秒
システム 4分58秒332

所要時間: 1061.926秒

答え4

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

ファイルが多すぎる場合は、次のようfindにパイプする必要があります。xargschmod

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

関連情報