個人用ディレクトリのバックアップをrsync
で台無しにした(NTFSファイルシステムでバックアップしている可能性があるため):すべてのファイルはここにありますが、すべてのファイルとディレクトリのアクセス権は777です。再帰的に変更されるmagicユーティリティでした:
シェルで行うのは簡単ですが、何時間もかかります...
副次的な質問:NTFSでLinuxディレクトリ階層を適切にバックアップするためのアドバイス(rsync
or other)。
標準的な推奨ソリューションは簡単です。
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 "{}" \;
_chmod -R a=,u+rwX,go+rX $DIR
_は正常に動作するようで、最も高速である可能性が非常に高いですが、それを見てください。
(私はstrace
でチェックしましたが、ファイル/ディレクトリごとにonefchmodat()
syscallのみを作成します-644のファイルと755のディレクトリの場合)。
コツは、_X
パーミッションで、_man chmod
_に文書化されています。これは、ディレクトリに対してのみx
のように機能します。
notと記載されているのは、それらが指定されたのと同じ順序で適用され、ランダムな順序だけでなく、複数のバリアントで繰り返しテストを行った結果、実際に実行されると確信していることです。与えられた順番で、私はこれが常にこのように機能するだろうと確信しています。
これはLinuxに関するものですが、chmodのBSDマンページをざっと読むと、-すべきでも機能することが示唆されています。
私は sitaramの回答 、 Peter Cordesのコメント 、 Fanatiqueの回答 、および harrymcの回答 をベンチマークしましたが、この答えは最も速い方法です。
平均:
完全な統計サマリー:
_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位でした。これにより、他の回答と比較してオーバーヘッドが大幅に削減されます。
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"
_
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秒
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秒
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秒
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秒
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秒
ディレクトリが大きすぎてファイルが多すぎる場合、@ harrymcが示した元の方法は失敗します。
ファイルが多すぎる場合は、find
とxargs
をchmod
でパイプする必要があります。
find /base/dir -type d -print0 | xargs -0 chmod 755
find /base/dir -type f -print0 | xargs -0 chmod 644