chmod рекурсивний дозвіл на тисячі файлів


16

Це більш загальне питання про "chmoding" рекурсивно.

У мене є цей скрипт, який у певний момент потребує рекурсивної зміни дозволів у папці, що містить кілька сотень тисяч файлів. У цю папку щодня додаються нові файли, але ті, які вже є, мають уже встановлені дозволи, і вони не змінюються.

Моє запитання ... коли я дзвоню

chmod 775. -R

чи намагається встановити дозвіл на файли, які вже мають правильні дозволи, або лише для нових файлів, які не мають правильних дозволів?

Здається, що завжди потрібні віки, щоб пройти цю команду в сценарії, хоча «нових» файлів всього кілька тисяч, і вони повинні робити свої дозволи досить швидко.

Я переглянув сторінку чоловіка для chmod, але, здається, нічого не згадує про цю справу.

Якщо chmod заздалегідь не перевірить дозволи, я повинен почати переглядати комбінацію 'find' з 'chmod'?


3
Цікаво, чи дійсно повільніше перевіряти дозволи та змінювати їх, якщо вони невірні, ніж безпосередньо встановлювати їх на правильне значення.
lgeorget

1
якщо хтось натрапляє на це і хоче команду find + chmod, ось це: find. ! -перма 775 -принт0 | xargs -0 -I {} chmod 775 {}
Тіті Думі

@lgeorget, значить, ви говорите, що повільніше використовувати find | chmod? ніж просто chmod все. (вибачте, не зрозуміли з вашого коментаря). ура
Тіті Думі

На мою скромну думку, це, мабуть, повільніше, оскільки потрібно запустити два процеси і перенаправити вихід першого на другий, але я не впевнений. Це залежить від часу, необхідного для встановлення дозволів, які можуть бути не настільки важливими, оскільки вони мають лише 3 байти для зміни в inode.
lgeorget

1
@depquid Основна проблема продуктивності тут - це зчитування даних у кеш диска. Після першого запуску все знаходиться в кеш-диску диска (якщо тільки замало пам'яті), таким чином ви протестуєте продуктивність чогось, що не є вузьким місцем у реальній ситуації.
Hauke ​​Laging

Відповіді:


9

chmodможуть або не можуть змінити дозволи файлів, які вже встановлені на те, що ви хочете, але якщо ні, то все одно потрібно перевірити їх, щоб побачити, які їх поточні дозволи [0]. Зі сотнями тисяч файлів, я не думаю, що це мало б значення; час, швидше за все, витрачається інструментами statкожного файлу.

Ви можете спробувати findперевірити наявність нових файлів, ніж останній запуск, або файли, які потрібно chmodзапустити, але я не думаю, що ви швидко покращите швидкість.

Якщо це можливо для вашого сценарію, ви, можливо, спочатку зможете перенести нові файли в окремий каталог, як область "тримання". Тоді ви можете chmodТОГО каталогу (у якому є лише нові файли), і в mvних з рештою. Це має бути значно швидше, але, на жаль, не працюватиме для кожної програми.

[0] Навіть якщо вона намагається встановити дозвіл на файли, які не потребують змін, основна файлова система, ймовірно, нічого не зробить із запитом, оскільки це непотрібно.


Дякую за це. Я спробую знайти | chmod версія та подивіться, чи робить це швидше. Якщо ні, то я спробую змінити сценарій, щоб він реалізував папку "hold", як ви запропонували.
Тіті Думі

Причина, чому ви не отримаєте підвищення швидкості, полягає в тому, що inode повинен зчитуватися як для ctime, так і для прав доступу.
Hauke ​​Laging

10

знайти / chmod оптимізацію

І те findй chmodінше треба читати

  1. всі записи каталогів
  2. вставки для всіх цих записів

Можливо, ви отримаєте поліпшення продуктивності, спочатку прочитавши всі записи, а потім усі вставки (на обертовому диску), оскільки тоді головка диска не переміщується між каталогом та введеннями). Оскільки chmod це дурно (як пояснює одна з інших відповідей), його слід називати findлише через . Але навіть тоді це може допомогти прочитати всі вставки до того, як буде записано перше (припустимо, що у вас є достатня кількість вільної оперативної пам’яті для кеш-диска). Я пропоную це:

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ІНГ всередині Docker контейнера.
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/, chmodоскільки пошук дає більше контролю над вибором речей.


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) та вихідним кодом процесу (ив) запису нових файлів.

  • Якщо ви використовуєте Linux, швидше за все, ваша система inotifyвключила підсистему ядра. У цьому випадку ви можете скласти сценарій ефективного рішення за допомогою [inotifywait (1)] (6).


Сторінка: якщо ви не хочете виконати дозволи на свої файли, я б запропонував змінити виклик так:

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

Примітка до редакції: мені заборонено додавати більше двох посилань до публікації, а також коментувати інші публікації. Я залишаю тут URL-адреси і сподіваюся, що якийсь відкритий користувач із достатньою репутацією поверне їх до тексту та видаляє цей параграф.


Прокоментуйте заливку кеш-диска за допомогою find . -printf "":

Це може пришвидшити виконання наступних chmodоперацій, однак залежить від наявної пам'яті та навантаження вводу / виводу. Так це може спрацювати, чи ні. Роз'єднання траверси ( find) та chmodоперації вже передбачає кешування, тому грунтування кешу може бути зайвим.

  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 / статті / прискорення об'ємного файлу-операції.html
  5. https + en.wikipedia.org / wiki / Умаск
  6. https + linux.die.net / man / 1 / inotifywait

0

Чи обдумували ви змінити процес (и), які створюють файл, щоб створити їх у режимі 0775? Подивіться на значення umask у навколишньому середовищі - 0002 може допомогти.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.