chmod izin rekursif pada ribuan file

16

Ini adalah pertanyaan yang lebih umum tentang 'chmoding' secara rekursif.

Saya memiliki skrip ini yang pada beberapa titik perlu mengubah izin secara rekursif dalam folder yang memiliki beberapa ratus ribu file. Ada file baru yang ditambahkan di folder itu setiap hari, tetapi yang sudah ada memiliki izin yang sudah ditetapkan dan tidak berubah.

Pertanyaan saya adalah ... ketika saya menelepon

chmod 775. -R

apakah itu mencoba mengatur izin untuk file yang sudah memiliki hak akses ditetapkan, atau hanya untuk file baru yang tidak memiliki izin yang tepat?

Tampaknya selalu butuh waktu lama untuk melewati perintah ini dalam skrip, meskipun file 'baru' hanya beberapa ribu dan harus melakukan izinnya dengan cukup cepat.

Saya telah melihat halaman manual untuk chmod, tetapi sepertinya tidak menyebutkan apa-apa tentang kasus ini.

Jika chmod tidak memeriksa izin sebelumnya, haruskah saya mulai mencari menggabungkan 'temukan' dengan 'chmod'?

Titi Dumi
sumber
3
Saya ingin tahu apakah benar-benar lambat untuk memeriksa izin dan mengubahnya jika tidak benar daripada langsung mengaturnya ke nilai yang benar.
lgeorget
1
jika ada yang menemukan ini dan menginginkan perintah find + chmod, ini dia: find. ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {}
Titi Dumi
@ lororget, jadi maksudmu lebih lambat menggunakan find | chmod? dari sekedar untuk chmod segalanya. (maaf, tidak mengerti dari komentar Anda). Cheers
Titi Dumi
Menurut pendapat saya yang sederhana, mungkin lebih lambat karena harus meluncurkan dua proses dan mengarahkan output dari yang pertama ke yang kedua, tetapi saya tidak yakin. Itu tergantung pada waktu yang diperlukan untuk mengatur izin yang mungkin tidak penting karena mereka hanya 3 byte untuk dimodifikasi dalam inode.
lgeorget
1
@depquid Masalah kinerja utama di sini adalah membaca data ke dalam cache disk. Setelah menjalankan pertama semuanya dalam cache disk (kecuali ada terlalu sedikit memori) sehingga Anda menguji kinerja sesuatu yang bukan hambatan dalam situasi nyata.
Hauke ​​Laging

Jawaban:

9

chmodmungkin atau mungkin tidak mengubah izin file yang sudah diatur ke apa yang Anda inginkan, tetapi jika tidak, masih perlu memeriksa mereka untuk melihat apa izin mereka saat ini [0]. Dengan ratusan ribu file, saya pikir itu tidak masalah; waktu kemungkinan besar dihabiskan oleh alat-alat di statsetiap file.

Anda dapat mencoba menggunakan finduntuk memeriksa file yang lebih baru daripada yang terakhir dijalankan atau file yang perlu chmoddijalankan, tapi saya rasa Anda tidak akan mendapatkan banyak peningkatan kecepatan.

Jika memungkinkan untuk skrip Anda, Anda mungkin bisa memasukkan file baru ke direktori terpisah terlebih dahulu, sebagai area "holding". Maka kamu bisachmod direktori ITU (yang hanya memiliki file baru), dan mvmereka dengan sisanya. Itu seharusnya jauh lebih cepat, tetapi sayangnya tidak akan bekerja untuk setiap aplikasi.

[0] Bahkan jika ia mencoba untuk mengatur izin file yang tidak memerlukan perubahan, sistem file yang mendasarinya mungkin tidak akan melakukan apa pun dengan permintaan, karena itu tidak perlu.

mrb
sumber
Terima kasih untuk itu. Saya akan mencoba mencari | versi chmod dan lihat apakah itu membuat segalanya lebih cepat. Jika tidak, saya akan mencoba memodifikasi skrip untuk mengimplementasikan folder 'holding' seperti yang Anda sarankan.
Titi Dumi
Alasan Anda tidak mendapatkan peningkatan kecepatan adalah karena inode harus dibaca untuk waktu dan hak akses.
Hauke ​​Laging
10

temukan / optimisasi chmod

Keduanya finddan chmodharus membaca

  1. semua entri direktori
  2. inode untuk semua entri ini

Anda mungkin mendapatkan peningkatan kinerja dengan terlebih dahulu membaca semua entri dan kemudian semua inode (pada disk yang berputar) karena kepala disk tidak bergerak antara direktori dan inode). Seperti chmod adalah bodoh (sebagai salah satu jawaban yang lain menjelaskan) itu harus disebut melalui findsaja. Tetapi meskipun demikian mungkin akan membantu untuk membaca semua inode sebelum yang pertama ditulis (dengan asumsi Anda memiliki cukup RAM gratis untuk cache disk). Saya menyarankan ini:

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

Solusi yang bagus: ACL

Solusi yang baik mungkin sangat berbeda: Jika file dibuat dalam direktori ini (dan tidak dipindahkan dari tempat lain) maka ACL dapat melakukan pekerjaan dengan cepat. Anda hanya perlu mengatur ACL default pada direktori induk.

Peningkatan lebih lanjut dapat dicapai dengan optimisasi sistem file. Jika ext3 / ext4 maka Anda dapat menjalankan e2fsck -Ddari waktu ke waktu. Mungkin ada baiknya menempatkan direktori ini ke volume yang terpisah. Anda dapat mencoba berbagai sistem file atau pengaturan sistem file (mis. Ukuran inode yang berbeda).

Hauke ​​Laging
sumber
ACL bagus selama Anda tidak bekerja pada mount NFSv4.
ostrokach
The findsolusi tentang dua kali lipat waktu saya, chmoding dalam sebuah wadah buruh pelabuhan.
Nathan ReinstateMonica Arthur
8

Dengan asumsi penggunaan chmoddari GNU coreutils paket pada Ubuntu 12.10.

chmod 775 . -Rmengeksekusi fchmodatpanggilan sistem untuk setiap file yang ditemukan terlepas dari apakah izin perlu diubah atau tidak. Saya mengkonfirmasi ini dengan memeriksa kode dan menggunakan strace chmod 775 . -R(snippet di bawah) untuk membuat daftar perilaku yang sebenarnya.

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

Ada beberapa kelemahan berjalan fchmodatdi setiap file

  • Panggilan sistem tambahan kemungkinan akan menjadi signifikan jika sejumlah besar file diubah. The find/ xargs/chmod yang disebutkan oleh orang lain kemungkinan akan lebih cepat dengan hanya mengubah file yang perlu diubah.
  • Panggilan untuk fchmodatmengubah modifikasi status file (waktu) dari setiap file. Ini akan menyebabkan setiap file / inode berubah setiap waktu dan kemungkinan akan menyebabkan kelebihan penulisan disk. Dimungkinkan untuk menggunakan opsi mount untuk menghentikan kelebihan penulisan ini.

Eksperimen sederhana menunjukkan perubahan waktu yang terjadi secara langsung 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

Tetapi ini tidak berubah untuk find/ xargs/ chmodbeberapa menit kemudian

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

Saya akan selalu cenderung menggunakan versi find/ xargs/ chmodkarena find memberi lebih banyak kontrol untuk memilih sesuatu.

Richm
sumber
1

[Sumber] (1) menunjukkan, yang chmod(1)selalu mencoba mengatur mode dan kemudian memeriksa kembali dengan [fstatat (2)] (2).

File diproses melalui [fts (3)] (3), yang harus 'stat' semua objek sistem file yang dilalui sebelumnya untuk membangun pohon datanya.

Unixlore memiliki [artikel yang bagus] (4) di mana chmod(1)waktunya melawan find/ xargspendekatan: yang terakhir menang dengan besar.

Di sini baris perintah disesuaikan dengan pertanyaan awal:

find . -print0 | xargs -0 chmod 775

Dua alasan:

  1. Traversal sistem file dipisahkan dari operasi pada file melalui pipa antara dua proses, yang bahkan mungkin berjalan pada core yang berbeda.

    1. fts(3)operasi diminimalkan, karena xargs(1)'meratakan' pohon direktori.

Jadi ya: Anda harus menggunakan find/ xargs. untuk solusi sederhana.

Pilihan lain:

  • Mainkan dengan [umask] (5) dan kode sumber dari proses menulis file baru.

  • Jika Anda menggunakan Linux, kemungkinan sistem Anda telah mengaktifkan inotifysubsistem kernel. Dalam hal ini, Anda dapat membuat skrip solusi yang efisien melalui [inotifywait (1)] (6).


Sidenote: kecuali jika Anda ingin mengeksekusi izin pada file Anda, saya sarankan untuk memodifikasi doa sebagai berikut:

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

Catatan untuk editor: Saya tidak diizinkan untuk menambahkan lebih dari dua tautan ke posting, tidak juga untuk mengomentari posting lain. Saya meninggalkan url di sini dan berharap beberapa pengguna berhati terbuka dengan reputasi yang cukup menempatkan mereka kembali ke teks dan menghapus paragraf ini.


Mengomentari priming cache disk denganfind . -printf "" :

Ini mungkin mempercepat pelaksanaan chmodoperasi berikut , namun tergantung pada memori yang tersedia dan beban i / o. Jadi mungkin berhasil, atau tidak. Decoupling traversal ( find) dan chmodoperasi sudah menyediakan caching, jadi priming cache mungkin berlebihan.

  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 / mempercepat-bulk-file-operations.html
  5. https + en.wikipedia.org / wiki / Umask
  6. https + linux.die.net / man / 1 / inotifywait
Georg Lehner
sumber
0

Sudahkah Anda mempertimbangkan untuk mengubah proses yang membuat file agar dibuat dengan mode 0775? Lihatlah nilai umask di lingkungan - 0002 dapat membantu.

D McKeon
sumber