chmod cho phép đệ quy trên hàng ngàn tệp


16

Đây là một câu hỏi tổng quát hơn về 'mã hóa' theo cách đệ quy.

Tôi có đoạn script này, tại một số điểm cần thay đổi đệ quy các quyền trong một thư mục có vài trăm nghìn tệp. Có những tệp mới được thêm vào thư mục đó mỗi ngày, nhưng những tệp đã có sẵn các quyền đã được đặt và chúng không thay đổi.

Câu hỏi của tôi là ... khi tôi gọi

chmod 775. -R

Có phải nó cố gắng đặt quyền cho các tệp đã được đặt quyền hay chỉ cho các tệp mới không có quyền phù hợp?

Dường như luôn mất nhiều thời gian để vượt qua lệnh này trong tập lệnh, mặc dù các tệp 'mới' chỉ có vài nghìn và nó sẽ thực hiện các quyền của chúng khá nhanh.

Tôi đã xem trang người đàn ông cho chmod, nhưng dường như không đề cập gì đến trường hợp này.

Nếu chmod không kiểm tra quyền trước, tôi có nên bắt đầu xem xét kết hợp 'tìm' với 'chmod' không?


3
Tôi tự hỏi nếu nó thực sự chậm hơn để kiểm tra các quyền và thay đổi chúng nếu chúng không đúng hơn là trực tiếp đặt chúng thành giá trị chính xác.
lgeorget

1
nếu có ai vấp phải điều này và muốn lệnh find + chmod, thì đây là: find. ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {}
Titi Dumi

@lgeorget, vậy bạn đang nói chậm hơn khi sử dụng find | chmod? hơn là chỉ để chmod tất cả mọi thứ. (xin lỗi, không hiểu từ bình luận của bạn). chúc mừng
Titi Dumi

Theo ý kiến ​​khiêm tốn của tôi, có lẽ sẽ chậm hơn vì cần phải xử lý hai quy trình và chuyển hướng đầu ra của quy trình đầu tiên sang quy trình thứ hai nhưng tôi không chắc chắn. Nó phụ thuộc vào thời gian cần thiết để thiết lập các quyền có thể không quan trọng vì chúng chỉ là 3 byte để sửa đổi trong nút.
lgeorget

1
@depquid Vấn đề hiệu năng chính ở đây là đọc dữ liệu vào bộ đệm đĩa. Sau lần chạy đầu tiên, mọi thứ đều nằm trong bộ đệm đĩa (trừ khi có quá ít bộ nhớ), do đó bạn đang kiểm tra hiệu năng của một thứ không phải là nút cổ chai trong tình huống thực.
Hauke ​​Laging

Câu trả lời:


9

chmodcó thể hoặc không thể thay đổi quyền của các tệp đã được đặt thành những gì bạn muốn, nhưng nếu không, vẫn cần kiểm tra chúng để xem các quyền hiện tại của chúng là gì [0]. Với hàng trăm ngàn tệp, tôi không nghĩ nó cũng quan trọng; thời gian rất có thể được sử dụng bởi các công cụ stating mỗi tập tin.

Bạn có thể thử sử dụng findđể kiểm tra các tệp mới hơn lần chạy trước hoặc các tệp cần chmodchạy, nhưng tôi không nghĩ bạn sẽ cải thiện được nhiều tốc độ.

Nếu có thể cho tập lệnh của bạn, trước tiên bạn có thể đưa các tệp mới vào một thư mục riêng, dưới dạng khu vực "giữ". Sau đó, bạn có thể chmodTHAT thư mục (chỉ có các tệp mới) và mvchúng ở cùng với phần còn lại. Điều đó sẽ nhanh hơn đáng kể, nhưng tiếc là sẽ không hoạt động cho mọi ứng dụng.

[0] Ngay cả khi nó cố gắng thiết lập quyền của các tệp không cần bất kỳ thay đổi nào, hệ thống tệp cơ bản có thể sẽ không làm bất cứ điều gì với yêu cầu, vì điều đó là không cần thiết.


Cảm ơn vì điều đó. Tôi sẽ thử tìm | phiên bản chmod và xem nếu nó làm cho mọi thứ nhanh hơn. Nếu không tôi sẽ cố gắng sửa đổi tập lệnh để thực hiện thư mục 'giữ' như bạn đề xuất.
Titi Dumi

Lý do bạn sẽ không được cải thiện tốc độ là vì nút phải được đọc cả về thời gian và quyền truy cập.
Hauke ​​Laging

10

tối ưu hóa tìm / chmod

Cả hai findchmodphải đọc

  1. tất cả các mục thư mục
  2. các nút cho tất cả các mục này

Bạn có thể có được sự cải thiện hiệu suất bằng cách trước tiên đọc tất cả các mục và sau đó là tất cả các nút (trên một đĩa quay) vì sau đó đầu đĩa không di chuyển giữa thư mục và các nút). Như chmod ngu ngốc (như một trong những câu trả lời khác giải thích) nó chỉ nên được gọi thông qua find. Nhưng ngay cả sau đó nó có thể giúp đọc tất cả các nút trước khi ghi đầu tiên (giả sử bạn có đủ RAM miễn phí cho bộ đệm đĩa). Tôi đề nghị điều này:

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

Giải pháp tốt: ACL

Giải pháp tốt có thể hoàn toàn khác: Nếu các tệp được tạo trong thư mục này (và không được di chuyển từ nơi khác) thì ACL có thể thực hiện công việc một cách nhanh chóng. Bạn chỉ cần đặt ACL mặc định trên thư mục mẹ.

Cải thiện hơn nữa có thể đạt được bằng cách tối ưu hóa hệ thống tập tin. Nếu đó là ext3 / ext4 thì thỉnh e2fsck -Dthoảng bạn có thể chạy . Có lẽ nó giúp đặt thư mục này vào một khối lượng riêng. Bạn có thể thử các hệ thống tệp hoặc cài đặt hệ thống tệp khác nhau (ví dụ: các kích thước inode khác nhau).


ACL là tốt miễn là bạn không làm việc trên ngàm NFSv4.
Ostrokach

Các findgiải pháp về tăng gấp đôi thời gian của tôi, chmoding bên trong một container Docker.
Nathan GoFundMonica Arthur

8

Giả sử việc sử dụng chmodtừ gói GNU coreutils trên Ubuntu 12.10.

chmod 775 . -Rthực hiện lệnh fchmodatgọi hệ thống cho mỗi tệp mà nó tìm thấy bất kể các quyền có cần thay đổi hay không. Tôi đã xác nhận điều này bằng cách kiểm tra mã và sử dụng strace chmod 775 . -R(đoạn trích bên dưới) để liệt kê hành vi thực tế.

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

Có một vài nhược điểm của việc chạy fchmodattrên mỗi tệp

  • Cuộc gọi hệ thống bổ sung có thể sẽ trở nên quan trọng nếu một số lượng lớn tệp được thay đổi. Các find/ xargs/ chmodphương pháp được đề cập bởi những người khác có thể sẽ nhanh hơn bằng cách chỉ thay đổi file mà không cần thay đổi.
  • Cuộc gọi để fchmodatthay đổi sửa đổi trạng thái tệp (ctime) của mỗi tệp. Điều này sẽ khiến mỗi tệp / inode thay đổi mỗi lần và có thể sẽ gây ra tình trạng ghi đĩa quá mức. Có thể sử dụng các tùy chọn gắn kết để dừng các ghi thừa này.

Một thử nghiệm đơn giản cho thấy những thay đổi thời gian xảy ra cho thẳng 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

Nhưng điều này không thay đổi trong find/ xargs/ chmodvài phút sau

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

Tôi sẽ luôn luôn có xu hướng sử dụng find/ xargs/ chmodphiên bản vì tìm cho kiểm soát tốt hơn việc lựa chọn mọi thứ.


1

[Nguồn] (1) hiển thị, chmod(1)luôn cố gắng đặt chế độ và sau đó kiểm tra lại bằng [fstatat (2)] (2).

Các tệp được xử lý thông qua [fts (3)] (3), trước đó phải 'thống kê' tất cả các đối tượng hệ thống tệp được duyệt qua để xây dựng cây dữ liệu của nó.

Unixlore có một [bài viết hay] (4) trong đó chmod(1)được định thời theo cách tiếp cận find/ xargs: cái sau chiến thắng bằng cường độ.

Ở đây dòng lệnh thích ứng với câu hỏi ban đầu:

find . -print0 | xargs -0 chmod 775

Hai lý do:

  1. Truyền tải hệ thống tệp được tách rời khỏi các hoạt động trên các tệp thông qua đường ống giữa hai quy trình, thậm chí có thể chạy trên các lõi khác nhau.

    1. fts(3)hoạt động được giảm thiểu, vì xargs(1)'làm phẳng' cây thư mục.

Vì vậy, có: bạn chắc chắn nên sử dụng find/ xargs. cho một giải pháp đơn giản.

Sự lựa chọn khác:

  • Chơi với [umask] (5) và mã nguồn của quá trình viết các tệp mới.

  • Nếu bạn đang sử dụng Linux, rất có thể hệ thống của bạn đã kích hoạt inotifyhệ thống con kernel. Trong trường hợp này, bạn có thể viết kịch bản một giải pháp hiệu quả thông qua [inotifywait (1)] (6).


Sidenote: trừ khi bạn muốn thực thi quyền trên các tệp của mình, tôi đề nghị sửa đổi lời gọi như sau:

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

Lưu ý cho các biên tập viên: Tôi không được phép thêm nhiều hơn hai liên kết đến bài đăng, không bình luận về các bài đăng khác. Tôi để các url ở đây và hy vọng một số người dùng không có uy tín sẽ đưa họ trở lại văn bản và xóa đoạn này.


Nhận xét về mồi bộ đệm đĩa với find . -printf "":

Điều này có thể tăng tốc độ thực hiện các chmodhoạt động sau , tuy nhiên phụ thuộc vào bộ nhớ khả dụng và tải i / o. Vì vậy, nó có thể làm việc, hoặc không. Việc tách riêng traversal ( find) và chmodthao tác đã cung cấp cho bộ đệm, do đó, việc lưu bộ đệm có thể là không cần thiết.

  1. https + lingrok.org / xref / coreutils / src / chmod.c # process_file
  2. https + linux.die.net / người đàn ông / 2 / fstatat
  3. https + linux.die.net / man / 3 / fts
  4. http + www.unixlore.net / bài viết / tăng tốc-hàng loạt-tập tin hoạt động.html
  5. https + vi.wikipedia.org / wiki / Umask
  6. https + linux.die.net / man / 1 / inotifywait

0

Bạn đã xem xét việc thay đổi (các) quá trình tạo tệp để tạo chúng với chế độ 0775 chưa? Nhìn vào giá trị umask trong môi trường - 0002 có thể giúp ích.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.