chmod ได้รับอนุญาตซ้ำกับไฟล์หลายพันไฟล์


16

นี่เป็นคำถามทั่วไปเกี่ยวกับ 'chmoding' แบบเรียกซ้ำ

ฉันมีสคริปต์นี้ซึ่งในบางจุดจำเป็นต้องเปลี่ยนการอนุญาตซ้ำในโฟลเดอร์ที่มีไฟล์สองสามแสนไฟล์ มีไฟล์ใหม่เพิ่มเข้ามาในโฟลเดอร์นั้นทุกวัน แต่ไฟล์ที่มีอยู่แล้วมีการตั้งค่าการอนุญาตแล้วและจะไม่เปลี่ยนแปลง

คำถามของฉันคือ ... เมื่อฉันโทร

chmod 775 -R

ลองตั้งค่าการอนุญาตสำหรับไฟล์ที่มีการตั้งค่าการอนุญาตที่เหมาะสมอยู่แล้วหรือเฉพาะสำหรับไฟล์ใหม่ที่ไม่มีการอนุญาตที่ถูกต้อง?

ดูเหมือนว่าจะต้องใช้เวลานานกว่าจะผ่านคำสั่งนี้ในสคริปต์แม้ว่าไฟล์ 'ใหม่' จะมีอยู่เพียงไม่กี่พันไฟล์เท่านั้นและควรจะอนุญาตอย่างรวดเร็ว

ฉันได้ดูหน้าคนสำหรับ chmod แต่ดูเหมือนจะไม่พูดถึงอะไรในกรณีนี้

หาก chmod ไม่ตรวจสอบการอนุญาตล่วงหน้าฉันควรเริ่มดูการรวม 'find' กับ 'chmod' หรือไม่


3
ฉันสงสัยว่ามันช้ากว่าจริงๆในการตรวจสอบสิทธิ์และเปลี่ยนแปลงพวกเขาหากพวกเขาไม่ถูกต้องกว่าตั้งโดยตรงพวกเขาเป็นค่าที่ถูกต้อง
lgeorget

1
หากใครก็ตามสะดุดกับสิ่งนี้และต้องการคำสั่ง find + chmod นี่คือ: find ! -perm 775 -print0 | xargs -0 -I {} chmod 775 {}
Titi Dumi

@lgeorget ดังนั้นคุณกำลังบอกว่ามันช้ากว่าที่จะใช้ find | chmod? มากกว่าเพียงแค่ทำทุกสิ่ง (ขออภัยไม่เข้าใจจากความคิดเห็นของคุณ) ไชโย
Titi Dumi

ในความเห็นที่ต่ำต้อยของฉันมันอาจจะช้ากว่าเพราะมันต้องใช้กระบวนการสองขั้นตอนและเปลี่ยนเส้นทางของผลลัพธ์แรกไปเป็นวินาที แต่ฉันไม่แน่ใจ ขึ้นอยู่กับเวลาที่ใช้ในการตั้งค่าการอนุญาตซึ่งอาจไม่สำคัญเนื่องจากมีเพียง 3 ไบต์ในการปรับเปลี่ยน inode
lgeorget

1
@depquid ปัญหาประสิทธิภาพหลักที่นี่คือการอ่านข้อมูลลงในแคชดิสก์ หลังจากการรันครั้งแรกทุกอย่างอยู่ในแคชดิสก์ (เว้นแต่มีหน่วยความจำน้อยเกินไป) ดังนั้นคุณกำลังทดสอบประสิทธิภาพของสิ่งที่ไม่ใช่คอขวดในสถานการณ์จริง
Hauke ​​Laging

คำตอบ:


9

chmodอาจหรืออาจไม่เปลี่ยนการอนุญาตของไฟล์ที่กำหนดไว้แล้วเป็นสิ่งที่คุณต้องการ แต่ถ้าไม่มันก็ยังคงต้องตรวจสอบพวกเขาเพื่อดูว่าการอนุญาตปัจจุบันของพวกเขาคืออะไร [0] ด้วยไฟล์หลายแสนไฟล์ฉันไม่คิดว่ามันจะมีความสำคัญ แต่อย่างใด เวลาน่าจะถูกใช้โดยเครื่องมือที่ใช้ในstatทุกไฟล์

คุณสามารถลองใช้findเพื่อตรวจสอบไฟล์ที่ใหม่กว่าการเรียกใช้ครั้งล่าสุดหรือไฟล์ที่ต้องchmodใช้งานได้ แต่ฉันไม่คิดว่าคุณจะได้รับการปรับปรุงความเร็วมากนัก

หากเป็นไปได้สำหรับสคริปต์ของคุณคุณอาจได้รับไฟล์ใหม่ที่ใส่ไว้ในไดเรกทอรีที่แยกต่างหากก่อนเป็นพื้นที่ "ถือ" จากนั้นคุณสามารถchmodไดเรกทอรีนั้น (ซึ่งมีไฟล์ใหม่เท่านั้น) และmvพวกเขาในส่วนที่เหลือ ควรจะเร็วกว่านี้มาก แต่น่าเสียดายที่จะไม่สามารถใช้ได้กับทุกแอปพลิเคชัน

[0] แม้ว่ามันจะพยายามตั้งค่าการอนุญาตของไฟล์ที่ไม่ต้องการการเปลี่ยนแปลงใด ๆ ก็ตาม แต่ระบบไฟล์ที่อยู่ข้างใต้อาจจะไม่ทำอะไรกับการร้องขอเพราะมันไม่จำเป็น


ขอบคุณสำหรับสิ่งนั้น ฉันจะลองหา | รุ่น chmod และดูว่ามันจะทำให้สิ่งต่าง ๆ เร็วขึ้น ถ้าไม่ใช่ฉันจะพยายามแก้ไขสคริปต์เพื่อใช้โฟลเดอร์ 'hold' ตามที่คุณแนะนำ
Titi Dumi

เหตุผลที่คุณจะไม่ได้รับการปรับปรุงความเร็วคือต้องมีการอ่าน inode ทั้งเวลาและสิทธิ์การเข้าถึง
Hauke ​​Laging

10

find / chmod optimization

ทั้งคู่findและchmodต้องอ่าน

  1. รายการไดเรกทอรีทั้งหมด
  2. inodes สำหรับรายการเหล่านี้ทั้งหมด

คุณอาจได้รับการปรับปรุงประสิทธิภาพโดยการอ่านรายการทั้งหมดก่อนแล้วจึง inodes ทั้งหมด (บนดิสก์หมุน) เพราะหัวดิสก์ไม่ย้ายระหว่างไดเรกทอรีและ inodes) ในฐานะที่chmod เป็นคนโง่ (เป็นหนึ่งในคำตอบอื่น ๆ อธิบาย) ก็ควรจะเรียกว่าผ่านfindเท่านั้น แต่ถึงอย่างนั้นมันก็อาจช่วยในการอ่าน inodes ทั้งหมดก่อนที่จะเขียนครั้งแรก (สมมติว่าคุณมี RAM เพียงพอสำหรับดิสก์แคช) ฉันแนะนำสิ่งนี้:

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

ทางออกที่ดี: ACL

ทางออกที่ดีอาจแตกต่างอย่างสิ้นเชิง: หากไฟล์ถูกสร้างขึ้นในไดเรกทอรีนี้ (และไม่ย้ายจากที่อื่น) จากนั้น ACL สามารถทำงานได้ทันที คุณเพียงแค่ต้องตั้งค่า ACL เริ่มต้นในไดเรกทอรีหลัก

การปรับปรุงเพิ่มเติมอาจทำได้โดยการปรับแต่งระบบไฟล์ ถ้ามันเป็น ext3 / ext4 คุณอาจทำงานเป็นe2fsck -Dครั้งคราว อาจช่วยวางไดเรกทอรีนี้ลงในไดรฟ์ข้อมูลที่แยกต่างหาก คุณอาจลองใช้ระบบไฟล์หรือการตั้งค่าระบบไฟล์ที่แตกต่างกัน (เช่นขนาดไอโหนดที่แตกต่างกัน)


ACL นั้นดีตราบใดที่คุณไม่ได้ทำงานกับการเมาท์ NFSv4
ostrokach

findวิธีการแก้ปัญหาเกี่ยวกับสองเท่าเวลาของฉัน, chmodไอเอ็นจีในภาชนะนักเทียบท่า
Nathan ReinstateMonica Arthur

8

สมมติว่าใช้chmodจากแพ็คเกจ GNU coreutilsบน Ubuntu 12.10

chmod 775 . -Rเรียกใช้การfchmodatเรียกระบบสำหรับแต่ละไฟล์ที่พบโดยไม่คำนึงว่าสิทธิ์นั้นจำเป็นต้องเปลี่ยนหรือไม่ ฉันยืนยันสิ่งนี้โดยทั้งการตรวจสอบรหัสและการใช้strace chmod 775 . -R(ตัวอย่างด้านล่าง) เพื่อแสดงรายการพฤติกรรมที่แท้จริง

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

มีข้อเสียสองประการในการทำงานfchmodatกับไฟล์แต่ละไฟล์

  • การเรียกใช้ระบบพิเศษจะมีความสำคัญหากมีการเปลี่ยนแปลงไฟล์จำนวนมาก กระบวนการfind/ xargs/ ที่chmodผู้อื่นกล่าวถึงจะทำได้เร็วกว่าโดยการเปลี่ยนเฉพาะไฟล์ที่จำเป็นต้องเปลี่ยนเท่านั้น
  • การเรียกเพื่อfchmodatเปลี่ยนแปลงการแก้ไขสถานะไฟล์ (ctime) ของแต่ละไฟล์ สิ่งนี้จะทำให้ทุกไฟล์ / inode เปลี่ยนไปในแต่ละครั้งและอาจทำให้เกิดการเขียนดิสก์มากเกินไป อาจเป็นไปได้ที่จะใช้ตัวเลือกการเมานต์เพื่อหยุดเขียนส่วนเกินเหล่านี้

การทดลองอย่างง่ายแสดงให้เห็นว่าการเปลี่ยนแปลงเวลาเกิดขึ้นโดยตรง 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

แต่สิ่งนี้จะไม่เปลี่ยนแปลงในfind/ xargs/ chmodสองสามนาทีในภายหลัง

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

ฉันมักจะใช้find/ xargs/ chmodversion เพราะ find ช่วยให้สามารถควบคุมสิ่งที่เลือกได้มากขึ้น


1

[แหล่งที่มา] (1) แสดงขึ้นซึ่งchmod(1)จะพยายามตั้งค่าโหมดจากนั้นกลับมาตรวจสอบอีกครั้งด้วย [fstatat (2)] (2)

ไฟล์จะถูกประมวลผลผ่าน [fts (3)] (3) ซึ่งจะต้องมี 'สถิติ' วัตถุระบบไฟล์ที่ผ่านการสำรวจทั้งหมดล่วงหน้าเพื่อสร้างแผนภูมิข้อมูล

Unixlore มี [บทความที่ดี] (4) ที่chmod(1)มีการกำหนดเวลากับfind/ xargsวิธีการ: หลังชนะโดยขนาด

ที่นี่บรรทัดคำสั่งปรับให้เข้ากับคำถามเดิม:

find . -print0 | xargs -0 chmod 775

เหตุผลสองประการ:

  1. การข้ามผ่านระบบไฟล์ถูกแยกออกจากการดำเนินการกับไฟล์ผ่านไพพ์ระหว่างสองกระบวนการซึ่งอาจทำงานบนแกนที่ต่างกัน

    1. fts(3)การดำเนินการจะลดลงเพราะxargs(1)'แบน' ออกจากต้นไม้ไดเรกทอรี

ดังนั้นใช่: คุณแน่นอนควรใช้/find xargsสำหรับทางออกที่ง่าย

ตัวเลือกอื่น:

  • เล่นกับ [umask] (5) และซอร์สโค้ดของกระบวนการ (es) ที่เขียนไฟล์ใหม่

  • หากคุณใช้ Linux โอกาสที่ระบบของคุณจะเปิดใช้งาน inotifyระบบย่อยเคอร์เนล ในกรณีนี้คุณสามารถสคริปต์โซลูชันที่มีประสิทธิภาพผ่าน [inotifywait (1)] (6)


Sidenote: หากคุณไม่ต้องการใช้การอนุญาตในไฟล์ของคุณฉันขอแนะนำให้แก้ไขการเรียกใช้ดังนี้:

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

หมายเหตุถึงบรรณาธิการ: ฉันไม่ได้รับอนุญาตให้เพิ่มมากกว่าสองลิงก์ไปยังโพสต์และไม่แสดงความคิดเห็นในโพสต์อื่น ฉันออกจาก URL ที่นี่และหวังว่าผู้ใช้ openhearted ที่มีชื่อเสียงเพียงพอจะทำให้พวกเขากลับมาเป็นข้อความและลบย่อหน้านี้


ความคิดเห็นเกี่ยวกับการเตรียมดิสก์แคชด้วยfind . -printf "":

สิ่งนี้อาจเพิ่มความเร็วในการดำเนินการของการดำเนินการต่อไปนี้chmodแต่ขึ้นอยู่กับหน่วยความจำที่มีอยู่และโหลดของ i / o ดังนั้นจึงอาจใช้งานได้หรือไม่ Decoupling traversal ( find) และchmodการดำเนินการได้เตรียมไว้แล้วสำหรับการแคชดังนั้นการทำแคชรองพื้นอาจไม่จำเป็น

  1. https + lingrok.org / XREF / coreutils / src / chmod.c # process_file
  2. https + linux.die.net / คน / 2 / fstatat
  3. https + linux.die.net / คน / 3 / FTS
  4. http + www.unixlore.net / บทความ / เร่งขึ้น-กลุ่มไฟล์ operations.html
  5. https + en.wikipedia.org / wiki / umask
  6. https + linux.die.net / คน / 1 / inotifywait

0

คุณได้พิจารณาเปลี่ยนกระบวนการที่สร้างไฟล์เพื่อสร้างด้วยโหมด 0775 หรือไม่? ดูค่า umask ในสภาพแวดล้อม - 0002 อาจช่วยได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.