Linux find and chmod

Linux find and chmod

Библиотека сайта rus-linux.net

locate является программа find : GNU find обходит каждый файл из дерева директорий, подставляя его имя в заданное выражение и проводит вычисление значения выражения слева до получения результата (правая часть выражения ложна для операции логического «и», истинна для логического «или»), на основании которого find принимает решение о выполнении заданного действия и переходит к рассмотрению следующего имени файла.

Программа find может принимать различные аргументы командной строки для создания выражения поиска, а стандартным действием при обнаружении файла с именем, удовлетворяющим выражению, является печать имени файла.

Перед тем, как как привести полезные примеры использования программы find с параметром exec , рассмотрим немного теоретических положений.

Параметры программы find

Наиболее известными параметрами для поиска файлов при помощи программы find , являются:

-name выражение Это наиболее часто используемый параметр для поиска файлов, имена которых (без учета предшествующих им директорий) удовлетворяют заданному выражению.

-mtime n Файлы были изменены n*24 часов назад.

  • ‘b’ для блоков по 512 байт (используется по умолчанию если суффикс не задан)
  • ‘c’ для байт
  • ‘w’ для двухбайтовых слов
  • ‘k’ для Килобайт (единицы размером в 1024 байта)
  • ‘M’ для Мегабайт (единицы размером в 1048576 байт)
  • ‘G’ для Гигабайт (единицы размером в 1073741824 байт)

-uid n Системный числовой идентификатор пользователя-владельца файла должен быть равен n .

Действия

При использовании find есть возможность для указания действий, которые будут выполнены при нахождении файла с именем, удовлетворяющим выражению поиска, а наиболее гибким вариантом, без сомнения, является использование параметра exec .

-exec команда; Выполнить команду; выполнение считается успешным в случае статуса выхода, равного нулю. Все символы, следующие за командой, считаются ее аргументами до того момента, как встречается символ «;» . Строка «<>» заменяется на имя рассматриваемого файла каждый раз, когда она встречается среди аргументов команды.

Примеры использования find с параметром exec

Поиск файлов и удаление их при помощи параметра exec является часто встречающимся вариантом использования этого параметра, но вам не нужно использовать exec для этих целей, так как более удачный вариант будет описан позднее.

find / -name "*.old" -exec /bin/rm <> \;
find / -size +100M -exec /bin/rm <> \;

Бывают и такие случаи, что программы «сходят с ума» и заполняют директории тысячами мелких файлов, при этом вы не сможете просто использовать команду rm * по той причине, что командная оболочка не в состоянии заменить символ * на имена всех этих файлов, зато в состоянии удалить эти файлы по очереди:

Помните, что вы не должны использовать эти примеры, поскольку для удаления файлов у GNU find есть параметр -delete , более безопасный, нежели «-exec /bin/rm <>;» . Пример использования:

В старых системах Unix у вас не будет возможности использовать параметр -delete , поэтому альтернатив параметру -exec для удаления файлов в них не остается.

Читайте также:  Kerio control vpn client linux deb amd64

А теперь рассмотрим некоторые другие примеры использования программы find с параметром exec .

find ./ -type f -exec chmod 644 <> \;

При помощи параметра -type f вы можете вести поиск только файлов и просто изменять права доступа к каждому из них при помощи chmod .

find / -user olduser -type f -exec chown newuser <> \;

В этом примере я использовал параметр -user как альтернативу параметру -uid .

find . -type d -exec chmod 755 <> \;

В этом примере я снова использовал параметр -type , но на этот раз с аргументом d для поиска директорий.

Заключение

Как вы убедились, в приведенных выше примерах показано то, что использование программы find с параметром exec позволяет вам выполнять довольно сложные задачи, при этом то обстоятельство, что вы можете выполнять заданное действие только над частью файлов, ставит вас в выигрышное положение.

Источник

Как изменить права только к файлам/каталогам?

Нужно задать права 755 только для каталогов и отдельно права 644 только для файлов. Как это сделать с помощью chmod?

find -type d -exec chmod 755 '<>' \; find -type f -exec chmod 644 '<>' \;

find -type d -exec chmod 755 <> \; find -type f -exec chmod 644 <> \;

Мне в последнее время больше нравится так:

Да, xargs как-то изящнее, но менее гибко.

Не проще ли find -type d -exec chmod 755 \*

На место «<>» — подставляется имя файла, кавычки нужны для экранирования символов-разделителей вроде пробела.

Не проще ли find -type d -exec chmod 755 \*

У меня такой вариант не работает, поэтому не понял.

Зато портабельнее — своими глазами видел find без exec-а! Честное слово видел! (Аж челюсть выпала — оно-ж даже на 386bsd было. )

man xargs
догадаешься почему — получишь печеньку

Когда мало файлов xargs быстрее, так как для каждого файла не вызывается chmod, это хотите сказать?

а ещё символ ‘ в имени файла

похоже, что без разницы — большой список или нет.

а ещё символ ‘ в имени файла

find -type d -print0 | xargs -0 chmod 755

не распарсил что ты пытался сказать, чем меньше execve — тем быстрее; вот с xargs их намноого меньше

Ок. Полагал, что xargs выполняет команду, только прочитав весь поток целиком.

хм. ну тут кагбе не распараллелишь, ибо всё упрётся в seek-time винта

Я о другом — xargs же разбивает полученный список по группам и для каждой группы выполняет execve->chmod, а не ждёт SIGPIPE/что-то_там и выполняет chmod для всего полученного списка из 100500 файлов.

вы бы прочитали man find, а потом лезли со своими учениями

А, всё, у xargs есть соответствующие ключи -L -n, отвечающие за разбивку. Тогда xargs в любых ситуациях лучше получается.

а если пробел в имени файла, срыватель покровов?

$ find -name "'" -maxdepth 1 -exec chmod -v 0000 <> + права доступа «./'» изменены на 0000 (---------)
$ mv "'" "' > '" $ find -name "'*" -maxdepth 1 | xargs chmod -v 1111 xargs: unmatched одинарная quote; by default quotes are special to xargs unless you use the -0 option $ find -name "'*" -maxdepth 1 -print0 | xargs -0 chmod -v 1111 права доступа «./'\n'» изменены на 1111 (--x--x--t)
$ find -name "'*" -maxdepth 1 -exec chmod -v 0222 <> \; права доступа «./'\n'» изменены на 0222 (-w--w--w-)

а если пробел в имени файла, срыватель покровов?

да хоть \r — УМВР. Сам проверь.

Читайте также:  What does make install do in linux

А, всё, у xargs есть соответствующие ключи -L -n, отвечающие за разбивку. Тогда xargs в любых ситуациях лучше получается.

find -name "'*" -maxdepth 1 -print0 | xargs -0 chmod -v 1111 find -name "'*" -maxdepth 1 -exec chmod -v 1111 <> +

А ещё такой вариант. Допустим, на одну из директорий установлены права 0000 и find выдаст ошибку чтения каталога. Тогда и +, и | xargs варианты завершатся с ошибкой и нужно явно вызывать для каждого объекта chmod?

Век живи, век учись. Не знал об x и X

ну если я правильно распарсил документацию — да. Очевидно, что xargs -0 нужно если требуется обработать имена найденных файлов. ИМХО.

Допустим, на одну из директорий установлены права 0000 и find выдаст ошибку чтения каталога. Тогда и +, и | xargs варианты завершатся с ошибкой и нужно явно вызывать для каждого объекта chmod?

нет. Существует 3 порядка (order) обхода дерева:

1. прямой: корень, потом поддеревья/листья.

2. обратный: поддеревья, а потом корень.

3. центрированый. Применяется в бинарных деревьях — левое поддерево — корень — правое. Для ФС не применяется, приходится всё сортировать с нуля.

Так вот, по умолчанию применяется 1й обход. Возможен chmod <> (конечно, если он разрешает права). А с ключом -depth производится 2й обход, и возможно удаление (-delete, -exec rm), и chmod, который запрещает доступ (даже тому, кто обходит).

Век живи, век учись. Не знал об x и X

на практике они очень редко помогают.

Тогда и +, и | xargs варианты завершатся с ошибкой

забыл сказать — xargs НЕ меняет порядок аргументов. В отличие например от *, которая не просто выдаёт список, но его сортирует по алфавиту. По этому, в частности, xargs на больших каталогах намного быстрее, особенно в UTF-8, чем звёздочка.

на практике они очень редко помогают.

Не думаю, что случай ТС-а уникален. У самого часто такая потребность возникала после копирования с флешек c fat.

Не думаю, что случай ТС-а уникален. У самого часто такая потребность возникала после копирования с флешек c fat.

Mount options for fat

(Note: fat is not a separate filesystem, but a common part of the msdos, umsdos and vfat filesystems.)

dmask=value Set the umask applied to directories only. The default is the umask of the current process. The value is given in octal.

fmask=value Set the umask applied to regular files only. The default is the umask of the current process. The value is given in octal.

Спасибо за информацию! Полагаю, что понял всё верно.
Меня вот какой случай интересует. Независимо от порядка обхода дерева очередной элемент дерева может находится в директории, для которой установлены права 0000, но xargs/+ не выполнили для неё chmod 755.

kolan@corka ~/tmp/find $ mkdir -p a/b/c mkdir: создан каталог «a» mkdir: создан каталог «a/b» mkdir: создан каталог «a/b/c» kolan@corka ~/tmp/find $ chmod 0000 a/b/c a/b a права доступа «a/b/c» изменены с 0775 (rwxrwxr-x) на 0000 (---------) права доступа «a/b» изменены с 0775 (rwxrwxr-x) на 0000 (---------) права доступа «a» изменены с 0775 (rwxrwxr-x) на 0000 (---------) kolan@corka ~/tmp/find $ ll . a a/b ls: невозможно получить доступ к a/b: Отказано в доступе .: итого 4 d--------- 3 kolan kolan 4096 апр. 29 12:25 a ls: невозможно открыть каталог a: Отказано в доступе kolan@corka ~/tmp/find $ find -type d -print0 | xargs -0 chmod -v 0777 find: `./a': Отказано в доступе права доступа «.» оставлены в виде 0777 (rwxrwxrwx) права доступа «./a» изменены с 0000 (---------) на 0777 (rwxrwxrwx) kolan@corka ~/tmp/find $ ll . a a/b .: итого 4 drwxrwxrwx 3 kolan kolan 4096 апр. 29 12:25 a a: итого 4 d--------- 3 kolan kolan 4096 апр. 29 12:25 b ls: невозможно открыть каталог a/b: Отказано в доступе kolan@corka ~/tmp/find $ find -type d -exec chmod -v 0777 <> + find: `./a/b': Отказано в доступе права доступа «.» оставлены в виде 0777 (rwxrwxrwx) права доступа «./a» оставлены в виде 0777 (rwxrwxrwx) права доступа «./a/b» изменены с 0000 (---------) на 0777 (rwxrwxrwx) kolan@corka ~/tmp/find $ ll . a a/b .: итого 4 drwxrwxrwx 3 kolan kolan 4096 апр. 29 12:25 a a: итого 4 drwxrwxrwx 3 kolan kolan 4096 апр. 29 12:25 b a/b: итого 4 d--------- 2 kolan kolan 4096 апр. 29 12:25 c 

Но без +, то есть когда в chmod передаются аргументы по одному, команда завершится без ошибок.

kolan@corka ~/tmp/find $ find -type d -exec chmod -v 0777 <> \; права доступа «.» оставлены в виде 0777 (rwxrwxrwx) права доступа «./a» изменены с 0000 (---------) на 0777 (rwxrwxrwx) права доступа «./a/b» изменены с 0000 (---------) на 0777 (rwxrwxrwx) права доступа «./a/b/c» изменены с 0000 (---------) на 0777 (rwxrwxrwx) kolan@corka ~/tmp/find $ ll . a a/b .: итого 4 drwxrwxrwx 3 kolan kolan 4096 апр. 29 12:25 a a: итого 4 drwxrwxrwx 3 kolan kolan 4096 апр. 29 12:25 b a/b: итого 4 drwxrwxrwx 2 kolan kolan 4096 апр. 29 12:25 c

Итого, если не известно, есть ли права на чтение+выполнение для низлежащих директорий, я так понимаю, оптимальным вариантом будет.

find -type d -exec chmod -v 0755 <> \; find -type f -exec chmod -v 0644 <> +
Вторая команда может быть заменена на xargs, если есть какие-то дополнительные требования к разбивке группы аргументов. 
find -type f -print0 | xargs -0 chmod -v 0644 

Источник

Оцените статью
Adblock
detector