В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13 |
Организация файловой системы
Приведем несколько примеров. Пусть нужно подсчитать число C-файлов в текущем каталоге и его подкаталогах. Воспользуемся следующим конвейером:
find . -name \*.c -print | wc -l
Обратим внимание на то, что команда find - одна из немногих, интерпретирующая шаблоны имен файлов самостоятельно. Собственно, у нее нет другого выхода, поскольку она должна рекурсивно обойти указанные иерархии и в каждой из них искать файлы, имена которых удовлетворяют заданному шаблону. Нетрудно заметить, что стандартный shell-механизм генерации имен файлов в данном случае не годится.
Рассмотрим более сложный пример. Нужно подсчитать суммарное число строк во всех C-файлах текущего каталога и его подкаталогов. Решений может быть несколько, рассмотрим три из них. Во-первых, можно организовать конвейер:
cat `find . -name \*.c -print` | wc -l
Утилита find отберет имена нужных файлов, cat выдаст их совокупное содержимое на стандартный вывод, а команда wc -l подсчитает общее число строк. По существу ту же идею можно выразить в другой форме:
find . -name \*.c -exec cat {} \; | wc -l
Здесь содержимое нужных файлов будет выдаваться на стандартный вывод по мере их обнаружения.
Наконец, можно поступить совсем просто, сделав нужные файлы аргументами команды wc. Правда, при этом будет выдаваться еще и число строк в каждом из C-файлов:
wc -l `find . -name \*.c -print`
Напишем теперь команду, позволяющую удалить из текущего каталога и его подкаталогов все файлы нулевого размера, а также объектные файлы, к которым не было доступа более месяца, запрашивая подтверждение (см. листинг 4.51). Обратим внимание на пробелы, окружающие экранированные скобки и экранированную точку с запятой.
find . \( -size 0c -o -name \*.o -a -atime +30 \) -ok rm {} \;Листинг 4.51. Еще один пример использования утилиты find.
Пусть на каталог /mnt смонтирован съемный носитель. Требуется выявить на нем файлы, владелец или группа которых на данной системе неизвестны, и изменить их на nobody. К цели ведет команда, показанная в листинге 4.52 (предполагается, что тот, кто ее выполняет, обладает соответствующими привилегиями).
find /mnt \( -nouser -o -nogroup \) -exec chown nobody:nobody {} \;Листинг 4.52. Пример выявления и обработки файлов с неизвестными владельцем или владеющей группой.
Если нужно обработать корневую файловую систему без учета смонтированных файловых систем, располагающихся на других устройствах, целесообразно воспользоваться командой вида find / -xdev... .
Две команды, показанные в листинге 4.53, почти эквивалентны: обе не заходят в подкаталоги с именем skip текущего каталога, но только вторая выводит их имена.
find . -name skip -prune -o -print find . -print -name skip -pruneЛистинг 4.53. Пример использования элементарного выражения -prune.
Одной из форм обхода и обработки файловой иерархии можно считать архивирование. Стандарт POSIX предусматривает для этого служебную программу pax:
pax [опция ...] [шаблон ...] pax -r [опция ...] [шаблон ...] pax -w [опция ...] [файл ...] pax -r -w [опция ...] [файл ...] каталог
Утилита pax поддерживает несколько архивных форматов, в число которых входят "родной" pax и унаследованные cpio и tar. В зависимости от заданной комбинации опций -r и -w pax осуществляет одну из четырех операций: выводит оглавление архива (первая из приведенных выше форм команды pax ), читает архив и извлекает из него файлы по заданным шаблонам имен (вторая форма), записывает заданные файлы в архив (третья форма) или копирует иерархии файлов (четвертая форма).
Как правило, архив читается со стандартного ввода, а записывается на стандартный вывод; если встречается файл типа " каталог ", обработке подвергается вся иерархия файлов с корнем в этом каталоге.
При извлечении файлов из архива разрешение маршрутных имен выполняется относительно того каталога, из которого утилита pax была вызвана.
Режим копирования можно представлять себе как комбинацию архивирования с последующим извлечением файлов в заданный каталог.
В листинге 4.54 представлены примеры использования команды pax. Первая архивирует содержимое текущего каталога, последняя копирует каталог old_dir в new_dir.
pax -w . mkdir new_dir pax -rw old_dir new_dirЛистинг 4.54. Пример использования служебной программы pax.