Все права на текст принадлежат автору: Дэвид Тейнсли.
Это короткий фрагмент для ознакомления с книгой.
Linux и UNIX: программирование в shell. Руководство разработчика.Дэвид Тейнсли

Введение

Настоящая книга посвящена shell–программированию, или, точнее, программированию в интерпретаторе Bourne shell.

Программирование на языке интерпретатора shell приобретает все большую популярность по мере утверждения Linux в качестве удобной в работе и отказоустойчивой операционной системы. Трудно оценить, какое количество пользователей работают с Linux. Эта операционная система распространяется бесплатно, хотя многие компании разрабатывают ее коммерческие варианты. Кроме того, несмотря на сделанные несколько лет назад неутешительные прогнозы специалистов относительно будущего UNIX, данная ОС также не теряет популярности, и число ее приверженцев продолжает расти.

Если вы хотите изучить shell–программирование, эта книга — для вас. Если же у вас имеется определенный опыт работы с интерпретатором shell, она послужит для вас хорошим справочным руководством. Кроме того, настоящее издание можно рассматривать как сборник советов по администрированию системы и кратких подсказок на все случаи жизни.

При написании книги во внимание принимались шесть основных положений:

   • читатель должен быстро освоить инструментальные средства интерпретатора shell, а также изучить основы программирования на языке shell;

   • книга должна служить не только руководством, но и справочником;

   • для повышения производительности системы читателю следует научиться писать shell–сценарии;

   • необходимо, чтобы shell–сценарии имели четкую и понятную структуру}

   • главы, по возможности, должны быть самодостаточными и независимыми друг от друга, что упрощает их изучение;

   • читатель должен уметь решать ряд административных задач, в частности создавать CGI–сценарии.

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

Если вы приступили к изучению shell–программирования, очевидно, у вас есть на то веские причины. Основные причины изучения shell–программирования заключаются в следующем:

   • язык программирования интерпретатора shell вполне самодостаточен, он содержит все необходимые управляющие конструкции и удобен в применении;

   • открывается возможность быстрого создания сценариев;

   • сценарии позволяют автоматизировать рутинные операции, выполняемые обычно вручную.

Интерпретатор bourne shell

Bourne shell является стандартным интерпретатором команд, который входит в состав всех систем UNIX и совместим с интерпретатором bash в Linux. В книге, посвященной shell–программированию и не привязанной к конкретной операционной системе, в качестве общего знаменателя должен рассматриваться именно Bourne shell. Учтите, что существуют и другие интерпретаторы, такие как bash, Korn shell и С shell. Если в вашей системе установлен интерпретатор bash, сценарии из этой книги будут выполняться в нем, поскольку bash совместим с Bourne shell. Синтаксис интерпретатора Korn shell близок к синтаксису рассматриваемого здесь языка.

Если внимательно изучить сценарии системной инсталляции, то можно обнаружить, что более чем на 95 процентов они являются сценариями Bourne shell. Это объясняется тем, что создатели сценариев знали: они будут выполняться в любой системе UNIX и Linux.

Переносимость интерпретатора shell

Если необходимо, чтобы создаваемый сценарий выполнялся под управлением любой системы, он должен обладать свойством переносимости. Переносимость сценариев определяется двумя основными факторами: • синтаксисом языка применяемого интерпретатора shell; • используемыми командами интерпретатора.

Проблемы, связанные с первым фактором, решаются автоматически, если сценарии создаются для интерпретатора Bourne shell.

Что касается второго фактора, то для большинства shell–сценариев характерна следующая особенность: по крайней мере, 20 процентов (а то и больше) их рабочего времени затрачивается на выполнение таких shell–команд, как cp, mv, mkdir и др. Здесь и заключена проблема переносимости. Дело в том, что поставщики разных операционных систем оснащают эти команды различными наборами опций. В нашей книге используются сценарии общего характера и применяются только те опции и команды, которые присутствуют как в System V, так и в BSD. Если же имеются какие‑либо различия, то приводятся альтернативные команды, но это случается сравнительно редко.

Структура книги

Книга представляет собой как руководство, так и справочник, поэтому ее главы можно читать в произвольном порядке. Если, например, вы хотите научиться включать в свои HTML–страницы CGI–сценарии, можете начать изучение материала даже с последней главы.

Книга состоит из пяти частей, посвященных различным аспектам программирования на языке интерпретатора shell.

Интерпретатор shell

В первой части книги рассматриваются общие вопросы, связанные с работой в интерпретаторе shell.

В главе 1 рассказывается о правах доступа к файлам и каталогам, а также о том, как создавать символические ссылки.

Чтобы на поиск созданного вами файла не уходило много времени, прочитайте

главу 2, посвященную команде find .

Вполне вероятно, что вы захотите выполнять сценарии в ночное или вечернее время. В этом случае вам следует изучить главу 3, в которой изложены сведения о планировании выполнения сценариев.

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

Фильтрация текста

Во второй части дается подробный обзор важнейших инструментов фильтрации текста. Фильтрация может выполняться в разное время: до того как данные поступят на вход сценария, в процессе выполнения сценария и при выводе текста на экран.

В отдельных главах описаны: grep — утилита поиска текстовых файлов (глава 8), awk — текстовый редактор, имеющий собственный язык сценариев (глава 9), sed — потоковый редактор, позволяющий выполнять быстрое редактирование (глава 10), и tr — утилита трансляции символов (глава 12). В главе 11 обсуждаются вопросы сортировки и объединения файлов, а также принципы работы с отдельными фрагментами текста.

Регистрация в системе

Третья часть посвящена вопросам регистрации в системе и настройки пользовательской среды. Каждый пользователь UNIX и Linux должен хорошо представлять, какие файлы выполняются в процессе регистрации,

В главе 14 подробно описаны механизмы управления локальными переменными интерпретатора shell и глобальными переменными среды,

В главе 15 даны рекомендации относительно того, как правильно употреблять различного рода кавычки и другие специальные символы интерпретатора shell, что позволит вам эффективно работать с системными переменными.

Основы shell–программирования

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

Глава 19 содержит описания функций. Кроме того, в ней представлены способы их многократного вызова из различных сценариев.

Важным моментом является передача аргументов сценарию интерпретатора shell. В главе 20 показано, как обрабатывать аргументы, переданные сценарию.

В главе 21 вы узнаете, как форматировать текст при выводе на экран. Отдельная глава, 22, посвящена вопросам обновления файлов. В главе 23 сосредоточены основные сведения об отладке сценариев.

Завершает данную часть обзор встроенных shell–команд, которые до этого не рассматривались.

Совершенствование навыков по написанию сценариев

В пятой части состоится знакомство с современными методами создания сценариев.

В главе 26 рассказывается, как посылать сигналы различным процессам и как перехватывать их, а также описывается специфическая конструкция "документ здесь", которая позволяет вручную вводить данные, ожидаемые сценарием.

Вам известно, почему при запуске системы автоматически загружаются некоторые программы? Это не будет для вас тайной, если вы ознакомитесь с главой 28, в которой мы поговорим об уровнях выполнения сценариев.

Глава 27 включает небольшую коллекцию полезных сценариев. Один из них позволяет запрещать другим пользователям доступ к вашим файлам, не модифицируя файл /etc/passwd.

Если вы интересуетесь вопросами разработки HTML–страниц, прочитайте главу 29, в которой рассматривается создание CGI–сценариев, но не с помощью языка Perl, а с помощью интерпретатора Bourne shell.

В книгу включены два приложения: приложение А, содержащее таблицу кодов ASCII, и приложение Б, в котором представлен ряд интересных shell–команд.

Что нужно знать

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

Чтобы запускать CGI–сценарии из главы 29, нужно располагать инсталлированным Web–сервером и иметь право выполнять CGI–сценарии.

Соглашения, принятые в книге

В книге употребляются следующие обозначения и шрифтовые выделения:


[Ctrl+клавиша] Означает нажатие указанной клавиши одновременно с клавишей [Ctrl]; например, [Ctrl+O] — это указание одновременно нажать клавиши [Ctrl] и [О]
Courier New Применяется во всех листингах сценариев, а также для обо значения результатов выполнения команд
Courier New Используется для выделения командной строки
В первых двух частях книги можно встретить примечания наподобие следующего:

В Linux…

Они служат для того, чтобы кратко описать различия между синтаксисом рассматриваемой команды в BSD/Linux и System V.

Приводимые в книге сценарии протестированы в Linux (Red Hat) и в AIX. Не которые сценарии протестированы в системе Data Generals.

ЧАСТЬ 1

Интерпретатор shell

ГЛАВА 1

Файлы и права доступа к ним

Если вы не хотите, чтобы кто угодно получал доступ к вашим файлам, изучите назначение битов режима. Благодаря им можно управлять доступом к файлам и каталогам, а также указывать тип доступа к создаваемым файлам. Это лишь небольшая часть системы безопасности в UNIX и Linux. Но на данный момент нас интересует не система безопасности в целом, а только та ее часть, которая имеет отношение к файлам и каталогам.

В этой главе рассматриваются следующие темы:

   • права доступа к файлам к каталогам;

   • биты смены идентификаторов {SUID и SGID);

   • изменение владельца файла или каталога с помощью команд chown и chgrp;

   • команда umask;

   • символические ссылки.

Файл принадлежит создавшему его пользователю, а также группе, членом которой данный пользователь является. Владелец файла может самостоятельно определять, кому позволено производить запись в файл, читать его содержимое, а также запускать файл на выполнение, если он является исполняемым.

Примечание:

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

Доступ к созданному файлу может осуществляться тремя способами:

   • Путем чтения, при этом содержимое файла отображается на экране.

   • Путем записи, при этом содержимое файла редактируется или удаляется.

   • Путем выполнения, если файл содержит сценарий интерпретатора shell либо является программой.

Пользователи, имеющие доступ к файлу, делятся на три категории:

   • Владелец файла, создавший его.

   • Члены группы, к которой относится владелец файла.

   • Остальные пользователи.

1.1. Информация о файлах

После создания файла система сохраняет о нем всю информацию, которая может когда‑либо понадобиться, в частности:

   • раздел диска, где физически находится файл;

   • тип файла;

   • размер файла;

   • идентификатор владельца файла, а также тех, кому разрешен доступ к файлу;

   • индексный дескриптор;

   • дата и время последнего изменения файла

   • режим доступа к файлу.

Рассмотрим типичный список файлов, полученный в результате выполнения команды ls -l.

$ ls -l

total 4232

-rwxr‑xr‑x 1 root root 3756 Oct 14 04:44 dmesg
-r‑xr‑xr‑x 1 root root 12708 Oct 3 05:40 ps
-rwxr‑xr‑x 1 root root 5388 Aug 5 1998 pwd
Информацию, предоставляемую командой ls -l, можно разбить на следующие части:


total 4232 Суммарный размер файлов в каталоге
-rwxr‑xr‑x Режим доступа к файлу, отображаемый в виде строки из десяти
символов. Первый символ ('-') указывает на то, что текущая запись
относится к файлу (если на его месте стоит символ d, значит,
запись относится к каталогу). Остальные символы делятся на три
категории:
rwx — права владельца (первая триада);
r‑x — права группы (вторая триада);
r‑x — права остальных пользователей (последняя триада).
Символ r означает право чтения, символ w — право записи,
символ x — право выполнения, символ ' — ' -oтсутствие соответ-
ствующего права. Система разрешений подробно описана ниже
1 Количество жестких ссылок на файл
root Идентификатор владельца файла
root Идентификатор группы, в которую входит владелец файла
3756 Размер файла в байтах
Oct 14 04:44 Дата и время последнего изменения файла
dmesg Имя файла

1.2. Типы файлов

В начале строки режима может стоять не только символ ' — " или d, ведь в каталоге насчитывается до семи различных типов записей (табл. 1.1):

Таблица 1.1. Типы файлов


d Каталог
l Символическая ссылка (указатель на другой файл)
s Сокет
b Специальный блочный файл
с Специальный символьный файл
p Файл именованного канала
Обычный файл или, если выразиться точнее, ни один из файлов, перечисленных выше

1.3. Права доступа к файлам

Давайте создадим файл, используя команду touch:

$ touch myfile

Теперь выполним команду ls -1:

$ ls -1 myfile

-rw‑r--r-- 1 dave admin 0 Feb 19 22:05 myfile


Мы получили пустой файл, и, как и ожидалось, первый символ в строке режима свидетельствует о том, что это обычный файл. В результате выполнения большинства операций по созданию файлов образуются либо обычные файлы, либо символические ссылки (о них говорится ниже).


Права владельца Права группы Права остальных пользователей
rw- r-- r--
Следующие три символа в строке режима (rw-) описывают права доступа к созданному файлу со стороны его владельца (пользователь dave). За ними следуют символы r--, указывающие на права группы, в которую входит этот пользователь (в данном случае он является членом группы admin). Последние три символа (r--) представляют собой права пользователей, не принадлежащих к данной группе.

Существует три вида разрешений:


r Право чтения данного файла
w Право записи/изменения данного файла
x Право выполнения данного файла, если он является сценарием или программой
Следовательно, строку режима для файла myfile необходимо интерпгретировать следующим образом:


- rw- r-- r--
Обычный файл Владелец может Пользователи указанной группы могут осуществлять только чтение этого файла Остальные пользователи также могут осуществлять только чтение этого файла
осуществлять чтение и запись этого файла
Возможно, вы обратили внимание на то, что при создании файла myfile владелец не получил право выполнять данный файл. Это связано с ограничениями, установленными по умолчанию в системе. Ситуация прояснится чуть позже, когда мы изучим команду umask.

Рассмотрим несколько дополнительных примеров (табл. 1.2).

Таблица 1.2. Примеры строк режима

Строка режима Результат


r-- --- --- Доступ к файлу разрешен только владельцу, который может читать содержимое файла, но не имеет права осуществлять запись в файл и выполнять его
r--r-- --- Доступ к файлу возможен только для чтения и разрешен владельцу и всем пользователям группы, в которую он входит
r--r--r-- Любой пользователь может получить доступ к файлу для чтения, остальные действия запрещены
rwx --- --- Владелец имеет полный доступ к файлу, для остальных пользователей файл недоступен
rwxr‑x --- Владелец имеет полный доступ к файлу; пользователи группы, в которую входит владелец, могут читать файл и запускать его на выполнение; для остальных пользователей файл недоступен
rwxr‑x r‑x Владелец имеет полный доступ к файлу; остальные пользователи могут читать файл и запускать его на выполнение
rw‑rw- --- Владелец и пользователи группы, в которую он входит, могут осуществлять чтение и запись файла; для остальных пользователей файл недоступен
rw‑rw‑r-- Владелец и пользователи группы, в которую он входит, могут осуществлять чтение и запись файла; остальным пользователям разрешено только чтение файла
rw‑rw‑rw- Все пользователи могут осуществлять чтение и запись файла

1.4. Изменение прав доступа к файлу

Вы можете изменять режим доступа к файлам, которыми владеете, с помощью команды chmod. Аргументы этой команды могут быть заданы либо в числовом виде (абсолютный режим), либо в символьном (символьный режим). Сначала рассмотрим символьный режим.

1.4.1. Символьный режим

Общий формат команды chmod для символьного режима таков:

chmod [кто] оператор [разрешения] файл

Значения параметра кто:

u Владелец

g Группа

o Другие пользователи

a Все (владелец, группа и другие пользователи)

Значения параметра оператор:

+ Добавление разрешения

— Удаление разрешения

= Установка заданного разрешения

Значения параметра разрешения:

r Право чтения

w Право записи

x Право выполнения

X Установка права выполнения только в том случае, если для какой‑либо категории пользователей уже задано право выполнения

s Установка бита SUID или SG1D для владельца или группы

t Установка sticky–бита[1]

u Установка тех же прав, что и у владельца

g Установка тех же прав, что и у группы

o Установка тех же прав, что и у других пользователей

1.4.2. Примеры использования команды chmod

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


Команда Строка режима Результат
chmod a‑x myfile rw‑rw‑rw- Отмена всех разрешений на выполнение
chmod og‑w myfile rw‑r--r-- Отмена разрешений на запись для группы и других пользователей
chmod g+w myfile rw‑rw‑r-- Добавление разрешения на запись для группы
chmod u+x myfile rwxrw‑r-- Добавление разрешения на выполнение для владельца
chmod go+x myfile rwxrwxr‑x Добавление разрешения на выполнение для группы и других пользователей
chmod g=o myfile rwxr‑x r‑x Предоставление группе тех прав, которые уже установлены для других пользователей

1.4.3. Абсолютный режим

Общий формат команды chmod для абсолютного режима таков:

chmod [режим] файл

Здесь параметр режим представляет собой восьмеричное число. В простейшем случае оно состоит из трех трехбитовых наборов, каждый из которых относится к соответствующей категории разрешений (владельца, группы, других пользователей). Старший бит

соответствует разрешению не чтение (1 — установлено, 0 -cнято), средний -pазрешению на запись, а младший -pазрешению на выполнение. Рассмотрим примеры:

Таблица 1.3. Восьмеричные значения Режима


Восьмеричное число Результат
400 Владелец имеет право чтения
200 Владелец имеет право записи
100 Владелец имеет право выполнения
040 Группа имеет право чтения
020 Группа имеет право записи
010 Группа имеет право выполнения
004 Другие пользователи имеют право чтения
002 Другие пользователи имеют право записи
001 Другие пользователи имеют право выполнения
Чтобы получить итоговое значение режима, который вы хотите задать для. своего файла, определите требуемый набор разрешений и сложите соответствующие числа в левой колонке таблицы.

Обратимся к примеру файла, который рассматривался ранее:

-rw‑r--r-- 1 dave admin 0 Feb 19 22:05 myfile

Его строка режима эквивалентна числу 644, сформированного таким образом:


право чтения и записи для владельца -400+200=600
+
право чтения для группы 040
+
право чтения для других пользователей 004
=644
Правило формирования восьмеричного режима доступа проще всего сформулировать с помощью следующей таблицы:

Таблица 1.4. Определение режима доступа к файлу


Владелец Группа Другие пользователи
rwx rwx rwx
4 + 2 + 1 4+2+1 4+2+1

1.4.4. Дополнительные примеры использования команды chmod

Ниже приведен ряд Примеров, иллюстрирующих применение команды chmod в абсолютном режиме:


Команда Строка режима Результат
chmod 666 rw‑rw‑rw- Установка разрешений на чтение и запись для владельца, группы и других пользователей
chmod 644 rw‑r--r-- Установка разрешений на чтение и запись для владельца; группа и остальные пользователи получают право чтения
chmod rwxr--r-- Предоставление полного доступа владельцу; группа и другие пользователи имеют право чтения
744
chmod rw‑rw‑r-- Установка разрешений на чтение и запись для владельца и группы; другим пользователям предоставляется право чтения
664
chmod Предоставление полного доступа только владельцу; остальным пользователям доступ запрещен
700
chmod r--r--r-- Все пользователи получают разрешение только на чтение
444
В качестве примера изменим права доступа к файлу myfile:

-rw‑r–r-- 1 dave admin 0 Feb 19 22:05 myfile

Необходимо, чтобы владелец имел полный доступ к файлу, а пользователи группы — только разрешение на чтение. Для этого введите следующую команду:

$ chmod 740 myfile

$ ls -l myfile

-rwxr 1 dave admin 0 Feb 19 22:05 myfile

Если другим пользователям также нужно дать разрешение на чтение, воспользуйтесь такой командой:

$ chmod 744 myfile

$ la -1 myfile

-rwxr--r-- 1 dave admin 0 Feb 19 22:05 myfile

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

$ chmod 664 *

В результате выполнения этой команды владелец и группа получат разрешения на чтение и запись всех файлов текущего каталога, а другие пользователи — только право чтения файлов. Чтобы действие данной команды рекурсивно распространилось на все подкаталоги, воспользуйтесь опцией -R:

$ chmod -R 664 *

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

1.5. Каталоги

Установка битов режима приобретает несколько иной смысл, когда команда chmod применяется по отношению к каталогу. Бит "чтения" означает возможность просмотра списка файлов в каталоге. Бит "записи" свидетельствует о том, что вам разрешается создавать и удалять файлы в данном каталоге. Наконец, бит "выполнения" указывает на возможность осуществления поиска файлов в каталоге и перехода в него.

Таблица 1.5. Праве доступа к каталогу


r w X
Возможность просмотра списка файлов в каталоге Возможность Возможность поиска файлов в каталоге и перехода в него
создания/удаления файлов в каталоге
Таблица 1.6. Примеры режимов доступа к каталогу


Строка режима Владелец Группа Другие пользователи
drwxrwxr‑x (775) Чтение, запись, Чтение, запись, Чтение, поиск
поиск поиск
drwxr‑xr- — (754) Чтение, запись, поиск Чтение, поиск Чтение
drwxr‑xr‑x (755) Чтение, запись, поиск Чтение, поиск Чтение, поиск
Когда строка режима для группы и других пользователей имеет значение -~х, никто не может просматривать содержимое каталога, кроме его владельца. Если каталог содержит сценарий или программу с установленным битом выполнения, пользователи по–прежнему могут выполнять их, указывая точное имя файла. При этом не имеет значения, может ли пользователь перейти в данный каталог.

Разрешения, установленные для каталога, имеют более высокий приоритет, чем разрешения, установленные для файлов этого каталога. Например, если есть каталог docs.

drwxr--r-- 1 louise admin 2390 Jul 23 09: 44 docs

а в нем — файл pay:

-rwxrwxrwx 1 louise admin 5567 Oct 3 05:40 pay

пользователь, который является членом группы admin и собирается редактировать файл pay, не сможет этого сделать из‑за отсутствия соответствующих прав доступа к каталогу- Этот файл доступен каждому, но поскольку бит поиска не установлен для группы admin, владеющей каталогом docs, ни один из пользователей группы не может получить доступ к каталогу. Если предпринимается попытка доступа, отображается сообщение "Permission denied" (доступ не разрешен).

1.6. Биты смены идентификаторов (SUID и SGID)

Биты SUID (Set User ID — установить идентификатор пользователя) и SGID (Set Group ID — установить идентификатор группы) были предметом жарких споров на протяжении многих лет. В некоторых системах установка этих битов не допускается либо они полностью игнорируются, даже если установлены. Это связано с тем, что при использовании данных битов возникает дополнительная угроза безопасности системы.

Идея, лежащая в основе применения бита SUID, состоит в том, что пользователь, запустивший программу, для которой владелец установил бит SUID, на время выполнения программы получает все права ее владельца. Если, например, администратор создал сценарий и установил для него бит SU1D, а другой пользователь запускает этот сценарий, привилегии администратора на время выполнения сценария переходят к пользователю. Тот же принцип применим и к биту SGID, только в данном случае меняются привилегии группы, владеющей сценарием.

1.6.1. Для чего нужны биты SUID и SGID?

Для чего нужны сценарии, при запуске которых происходит смена идентификаторов? Сейчас я попытаюсь объяснить. Я отвечаю за администрирование нескольких больших баз данных. Чтобы выполнить операцию по их резервированию, требуется специальный профильный файл администратора. Я создал несколько сценариев и установил для них бит SG1D, благодаря чему пользователи, которым разрешен запуск этих сценариев, не обязаны регистрироваться а качестве администраторов баз данных. А это, в свою очередь, уменьшает риск случайного повреждения информации на сервере. При запуске указанных сценариев пользователи получают разрешение на выполнение операций по выгрузке базы данных, хотя обычно такое право предоставляется только административному персоналу. После завершения сценариев восстанавливаются изначальные права пользователей.

Существует несколько системных команд UNIX, для которых установлен бит SUID или SGID. Чтобы найти эти команды, перейдите в каталог /bin или /sbin и введите:

$ ls -l | grep '^…s'

Вы получите список команд с установленным битом SUID.

$ ls -1 | grep '^…s..s'

В результате выполнения этой команды выводится список команд, у которых установлен как бит SUID, так и бит SGID.

1.6.2. Установка битов SUID и SGID

Чтобы установить бит SUID, вставьте цифру 4 перед числом, задающим режим доступа. Биту SGID соответствует цифра 2. Если одновременно устанавливаются оба бита, следует ввести цифру 6 (4 + 2).

В строке режима установленные биты SUID и SGID обозначаются символом s, который помещается на место символа x в первую или вторую триаду соответственно. Помните, что сам бит выполнения (х) также должен быть установлен. Если, например, вы хотите для какой‑либо программы установить бит SGID, убедитесь в том, что группа обладает правом выполнения этой программы.

Примечание:

Команда chmod не запрещает вам установить бит SUID или SGID при отсутствии соответствующего разрешения на выполнение файла. В этом случае при выполнении команды ls -l в строке режима будет указан символ S, а не s. Система таким образом информирует вас о неправильной установке прав доступа к файлу.

Рассмотрим несколько примеров:


Команда Строка режима Результат
chmod 4755 rwsr‑xr‑x Для файла установлен бит SUID; владелец имеет право чтения, записи и выполнения; группа и другие пользователи имеют право чтения и выполнения
chmod 6711 rws--s — х Для файла установлены биты SUID и SGID; владелец имеет право чтения, записи и выполнения; группа и другие пользователи имеют право выполнения
chmod 2751 rwxr‑s--x Для файла установлен бит SGID; владелец имеет право чтения, записи и выполнения; группа имеет право чтения и выполнения; другие пользователи имеют право выполнения
Для установки битов SUID и SGID можно также воспользоваться символьными

операторами команды chmod. Вот как это делается:

chmod u+s имя_файла — SUID

chmod g+s имя_файла — SGID

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

1.7. Команды chown и chgrp

Создав файл, вы автоматически становитесь его владельцем, но можете передать право владения другому пользователю, у которого есть запись в файле /etc/passwd. Только системный администратор либо фактический владелец может передавать права на файл другому пользователю. Если вы отказались от владения файлом, для того чтобы восстановить свои права на него, вам придется обратиться к системному администратору.

Для передачи прав владельца предназначена команда chown. Команда chgrp задает группу, которой принадлежит файл. Общий формат этих команд таков:

chown владелец файл chgrp владелец файл

Опция -R позволяет выполнить рекурсивное изменение файлов в указанном каталоге и всех его подкаталогах.

1.7.1. Пример использования команды chown

Вот как можно поменять владельца файла с помощью команды chown:

$ ls -l

-rwxrwxrwx 1 louise admin 345 Sep 20 14:33 project

$ chown pauline project

$ ls -l

-rwxrwxrwx 1 pauline admin 345 Sep 20 14:33 project

Право владения файлом project переходит от пользователя louise к пользователю

pauline.

1.7.2. Пример использования команды chgrp

Следующий пример демонстрирует, как поменять группу, которой принадлежит файл:

$ ls -1

-rwxrwxrwx 1 pauline admin 345 Sep 20 14:33 project

$ chgrp sysadmin project

$ ls -1

-rwxrwxrwx 1 pauline sysadmin 345 Sep 20 14:33 project

Пользователь pauline передал группе sysadmin право владения файлом project, которое до этого принадлежало группе admin.

1.7.3. Определение групп, в состав которых вы входите

Если вы хотите узнать, к какой группе принадлежите, введите команду groups:

$ groups

admin sysadmin appsgen general

либо воспользуйтесь командой id:

$ id

uid=0(root) gid=0(root) groups=0(root), 1(bin), 2(daemon), 3(sys), 4(ado)

1.7.4. Определение групп, в состав которых входят другие пользователи

Определить, в состав каких групп входит другой пользователь, позволяет команда groups, в качестве аргумента которой указано имя пользователя:

$ groups matty

sysadmin appsgen post

Данная команда сообщает о том, что пользователь matty входит в состав групп

sysadmin, appsgen и post.

1.8. Команда umask

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

Как правило, значение umask устанавливается в файле /etc/profile, доступ к которому имеют все пользователи. Поэтому, если вы хотите установить общесистемное значение umask, отредактируйте данный файл (для этого нужно иметь права администратора). Свое собственное значение umask можно задать в файле .profile или .bash_profile, находящемся в каталоге /home.

1.8.1. Обработка значений umask

Команда umask задает восьмеричное число, которое при создании каждого файла и каталога вычитается из стандартного значения режима доступа. Полученное значение режима присваивается файлу или каталогу. Стандартному режиму доступа к каталогам соответствует число 777, а режиму доступа к файлам — 666 (система не позволяет создавать текстовые файлы с установленными битами выполнения, эти биты следует добавлять отдельно с помощью команды chmod). Значение umask также состоит из трех трехбитовых наборов: для владельца, группы и других пользователей.

Общий формат команды umask таков:

umask nnn

где nnn — это маска режима в диапазоне от 000 до 777.

Ниже показано; как на основании значения umask определить режим доступа к файлу или каталогу (табл. 1.8).

Таблица 1.8. Интерпретация значения umask


Цифра в значении umask Результат для файла Результат для каталога
0 6 7
1 6 6
2 4 5
3 4 4
4 2 3
5 2 2
6 0 1
7 0 0
Из таблицы следует, что, например, значению umask, равному 002, соответствует режим 664 для файлов и 775 для каталогов.

Если вам удобнее работать со строками режима, руководствуйтесь описанной ниже последовательностью действий. Предположим, значение umask равно 002.

   • Сначала запишите полную строку режима, эквивалентную числу 777.

   • Под ней запишите строку режима, соответствующую значению umask (002).

   • Вычеркните из первой строки те символы, которые дублируются в тех же позициях во второй строке. Вы получите строку режима для каталогов.

   • Вычеркните из полученной строки все символы x. Вы получите строку режима для файлов.


1. Полная строка режима rwxrwxrwx (777)
2. Значение umask (002) w-
3. Строка режима для каталогов rwxrwxr-x (775)
4. Строка режима для файлов rw‑rw‑r-- (664)

1.8.2. Примеры установки значений umask

В табл. 1.9 представлены некоторые возможные значения umask и указаны соответствующие им режимы доступа к файлам и каталогам.

Таблица 1.9. Примеры значений umask


Значение umask Режим доступа к каталогам Режим доступа к файлам
022 755 644
027 750 640
002 775 664
006 771 660
007 770 660
Для просмотра текущего значения umask введите команду umask без параметров.

$ umask

022

$ touch file1

$ 1s -1 file1

-rw‑r--r-- 1 dave admin 0 Feb 18 42:05 file1

Чтобы изменить существующую установку, просто укажите новый аргумент команды umask:

$ umask 002

Убедимся в том, что система приняла изменения:

$ umask

002

$ touch file2

$ ls -l file2

-rw‑rw‑r-- 1 dave admin 0 Feb 18 45:0? file2

1.9. Символические ссылки

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

1.9.1. Применение символических ссылок

Предположим, у нас есть файл с информацией о продажах, находящийся в каталоге /usr/locai/admin/sales. Необходимо, чтобы каждый пользователь мог работать с этим файлом. Вместо того чтобы создавать множество копий файла в пользовательских каталогах, можно образовать в них символические ссылки, которые указывают на исходный файл в каталоге /usr/local/admin/sales. Тогда о всех изменениях, производимых в файле любым пользователем, немедленно узнают остальные пользователи. Имена символических ссылок могут быть произвольными и не обязаны совпадать с именем исходного файла.

Ссылки удобны в том случае, когда для получения доступа к файлу необходимо пройти через большое количество подкаталогов. Вместо этого можно создать ссылку в текущем каталоге, которая будет указывать на подкаталог, глубоко "спрятанный" в недрах других подкаталогов. Это также избавляет вас от необходимости запоминать местоположение таких файлов.

1.9.2. Примеры создания символических ссылок

Символическая ссылка создается с помощью команды ln -s, формат которой таков:

ln -s исхолный_файл [имя_ссылки]

Если имя ссылки не указано, будет создана ссылка, имя которой совпадает с именем исходного файла.

Рассмотрим случай, когда в системе регистрируются 40 пользователей, относящихся к двум группам — менеджеры (sales) и административный персонал (admin). Для каждой группы при входе в систему должны быть заданы свои установки. Сначала

я удалю все профильные файлы (.profile) во всех пользовательских начальных каталогах, а затем создам в каталоге /usr/local/menus два новых профильных файла — sales.profile и admin.profile. В начальном каталоге каждого пользователя необходимо создать символическую ссылку на один из этих двух файлов. Вот как это делается для пользователя matty, являющегося членом группы sales:

$ cd /home/sales/matty

$ rm .profile

$ ln -s /usr/local/menus/sales.profile .profile

$ ls -la .profile

lrwxrwxrwx 1 matty sales 5567 Oct 3 05:40 .profile -> /usr/local/menus/sales.profile

Аналогичные действия выполняются для всех пользователей. Теперь для изменения любого из профилей достаточно поменять всего один файл — либо sales.profile, либо admin.profile.

Когда ссылка больше не нужна, ее можно удалить. Однако помните, что при удалении исходного файла символическая ссылка не удаляется автоматически, а лишь становится недействительной. При обращении к ней выводится сообщение "No such file оr directory" (нет такого файла или каталога).

Символическая ссылка может указывать на файл или каталог, находящийся в другой файловой системе. Следует только учитывать, что у вас должно быть право поиска во всех каталогах, перечисленных в путевом имени к исходному файлу. Режим доступа к ссылке устанавливается равным 777 (rwxrwxrwx), но режим доступа к исходному файлу не меняется.

После инсталляции новой системы мне часто приходится создавать ссылку на каталог /tmp из каталога /var, так как некоторые приложения рассчитывают на каталог /var/tmp (а он не всегда существует) для размещения в нем своих временных файлов. Чтобы хранить все временные файлы в одном месте и не создавать новый каталог, я формирую символическую ссылку:

$ ln -s /tmp /var/tmp $ cd /var $ ls -l

lrwxrwxrwx 1 root root 5567 Sep 9 10:40 tmp -> /tmp

1.10. Заключение

Эта глава содержит базовые сведения о системе безопасности файлов. Будьте предельно внимательны, реализуя наши рекомендации. Небольшая ошибка при вводе команды chmod -R из корневого каталога может привести к огромным затратам времени на то, чтобы восстановить для файлов корректный режим доступа.

Создание сценариев с установленным битом SUID является весьма удобным. Но старайтесь осторожно применять SUID–сценарии, обеспечивающие предоставление прав пользователя root.

ГЛАВА 2

Команды find и xargs

Часто в процессе работы возникает необходимость осуществить поиск файлов с определенными характеристиками, такими как права доступа, размер, тип и т. д. Команда find представляет собой универсальный инструмент поиска: она позволяет искать файлы и каталоги, просматривать все каталоги в системе или только текущий каталог.

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

   • параметры команды find;

   • примеры использования различных опций команды find;

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

Возможности команды find обширны, велик и список предлагаемых опций. В настоящей главе описаны наиболее важные из них. Команда find может проводить поиск даже на дисках NFS (Network File System -cетевая файловая система), конечно, при наличии соответствующих разрешений. В подобных случаях команда обычно выполняется в фоновом режиме, поскольку просмотр дерева каталогов требует значительных затрат времени.

Общий формат команды find таков:

find путевое_имя -oпции

где путевое_имя — это каталог, с которого необходимо начинать поиск. Символ '.' служит для обозначения текущего каталога, символ '/' — корневого каталога, а символ '~' — записанного в переменной $НОМЕ начального каталога текущего пользователя.

2.1. Опции команды find

Остановимся на описании основных опций команды find . Таблица 2.1. Основные опции команды find


-name Поиск файлов, имена которых соответствуют заданному шаблону
-print Запись полных имен найденных файлов в стандартный поток вывода
-perm Поиск файлов, для которых установлен указанный режим доступа
-prune Применяется для того, чтобы команда find не выполняла рекурсивный поиск по уже найденному путевому имени; если указана опция -depth, опция -prune игнорируется
-user Поиск файлов, принадлежащих указанном пользователю
-group Поиск файлов, которые принадлежат данной группе
-mtime -n +n Поиск файлов, содержимое которых модифицировалось менее чем (-) или более чем (+) n дней назад; имеются также опции -atime и -ctime, которые позволяют осуществлять поиск файлов соответственно по дате последнего чтения и дате последнего изменения атрибутов файла
-nogroup Поиск файлов, принадлежащих несуществующей группе, для которой, иначе говоря, отсутствует запись в файле /etc/groups
-nouser Поиск файлов, принадлежащих несуществующему пользователю, для которого, другими словами, отсутствует запись в файле
/etc/passwd
-newer файл Поиск файлов, которые созданы позднее, чем указанный файл
-type Поиск файлов определенного типа, а именно:
b -cпециальный блочный файл;
d — каталог;
с -cпециальный символьный файл;
p — именованный канал;
1 -cимволическая ссылка;
s -cокет;
f -oбычный файл
-size n Поиск файлов, размер которых составляет n единиц; возможны
следующие единицы измерения:
b — блок размером 512 байтов (установка по умолчанию);
c — байт;
k — килобайт (1024 байта);
w — двухбайтовое слово
-depth При поиске файлов сначала просматривается содержимое текущего каталога и лишь затем проверяется запись, соответствующая самому каталогу
-fstype Поиск файлов, которые находятся в файловой системе определенного типа; обычно соответствующие сведения хранятся в файле /etc/fstab, который содержит данные о файловых системах, используемых на локальном компьютере
-mount Поиск файлов только в текущей файловой системе; аналогом этой опции является опция -xdev
-exec Выполнение команды интерпретатора shell для всех обнаруженных
файлов; выполняемые команды имеют формат
команда {} \;
(обратите внимание на наличие пробела между символами {} и
-ok Аналогична опции -exec, но перед выполнением команды отображается запрос

2.1.1. Опция -name

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

Если необходимо найти все файлы с расширением txt в вашем начальном каталоге, укажите символ '~' в качестве путевого имени. Имя начального каталога будет извлечено из переменной $номе.

$ find ~ -name "*.txt" — print

Чтобы найти все файлы с расширением txt, находящиеся в текущем каталоге, следует воспользоваться такой командой:

$ find . — name "*.txt" — print

Для нахождения в текущем каталоге всех файлов, в именах которых встречается хотя бы один символ в верхнем регистре, введите следующую команду:

$ find . — name "[A‑Z]*" — print

Найти в каталоге /etc файлы, имена которых начинаются с символов "host", позволяет команда

$ find /etc -name "host*" — print

Поиск в начальном каталоге всех файлов с расширением txt, а также файлов, имена которых начинаются с точки, производит команда

$ find ~ -name "*.txt" — print -o -name ".*" — print

Опция -o является обозначением операции логического ИЛИ. В случае ее применения помимо файлов с обычными именами будут найдены файлы, имена которых начинаются с точки.

Если вы хотите получить список всех файлов в системе, не имеющих расширения, выполните представленную ниже команду, «о будьте осторожны, так как она может существенно замедлить работу системы:

$ find / -name "*" — print

Ниже показано, как найти все файлы, в именах которых сначала следуют символы нижнего регистра, а за ними — две цифры и расширение .txt (например, ах37.txt):

$ find . — name "[a‑z][a‑z][0—9][0—9].txt" — print

2.1.2. Опция -perm

Опция -perm позволяет находить файлы с заданным режимом доступа. Например, для поиска файлов с режимом доступа 755 (их может просматривать и выполнять любой пользователь, но только владелец имеет право осуществлять запись) следует воспользоваться такой командой:

$ find . — perm 755 -print

Если перед значением режима вставить дефис, будет произведен поиск файлов, Для которых установлены все указанные биты разрешений, остальные биты при этом

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

$ find . — perm -007 -print

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

2.1.3. Опция -prune

Когда вы не хотите вести поиск в том или ином каталоге, воспользуйтесь опцией -prune. Она служит указанием остановить поиск на текущем путевом имени. Если путевое имя указывает на каталог, команда find не будет заходить в него. При наличии опции -depth опция -prune игнорируется.

Следующая команда проводит поиск в текущем каталоге, не заходя в подкаталог /bin:

$ find . — name "bin" — prune -o -print

2.1.4. Опции -user и -nouser

Чтобы найти файлы, принадлежащие определенному пользователю, укажите в команде find опцию -user, а также имя пользователя. Например, поиск в начальном каталоге файлов, принадлежащих пользователю dave, осуществляется посредством такой команды:

$ find ~ -user dave -print

Поиск в каталоге /etc файлов, принадлежащих пользователю uucp, выполняет

следующая команда: |

$ find /etc -user uucp -print

Благодаря опции -nouser возможен поиск файлов, принадлежащих несуществующим пользователям. При ее использовании производится поиск файлов, для владельцев которых нет записи в файле /etc/passwd. Конкретное имя пользователя указывать не нужно: команда find выполняет всю необходимую работу сама. Чтобы найти все файлы, которые принадлежат несуществующим пользователям и находятся в каталоге /hоте, задайте вот такую команду:

$ find /home -nouser -print

2.1.5. Опции -group и -nogroup

Опции -group и -nogroup аналогичны опциям -user и -nouser и позволяют искать файлы, принадлежащие заданной группе или несуществующим группам. Ниже приведена команда для нахождения в каталоге /apps всех файлов, которыми владеют пользователи группы accts:

$ find /apps -group accts -print

Следующая команда ищет во всей системе файлы, принадлежащие несуществующим группам:

$ find / -nogroup -print

2.1.6. Опция -mtime

Опцию -mtime следует применять при поиске файлов, доступ к которым осуществлялся x дней назад. Если аргумент опции снабдить знаком ' — ', будут отобраны файлы, к которым не было доступа в течение x дней. Аргумент со знаком '+' приводит к противоположному результату — производится отбор файлов, доступ к которым осуществлялся на протяжении последних х дней.

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

$ find / -mtime -5 -print

Ниже приведена команда, выполняющая поиск в каталоге /var/adm файлов, которые обновлялись в течение последних трех дней:

$ find /var/adm -mtime +3 -print

2.1.7. Опция -newer

Если необходимо найти файлы, доступ к которым осуществлялся в промежутке времени между обновлениями двух заданных файлов, воспользуйтесь опцией -newer. Общий формат ее применения таков:

-newer старый_файл ! —newer новый_файл

Знак '!' является оператором логического отрицания. Он означает: найти файлы, которые новее, чем старый_файл, но старее, чем новый_файл.

Предположим, у нас есть два файла, которые обновлялись с интервалом немногим более двух дней:


rwxr‑xr‑x 1 root root 92 Apr 18 11:18 age.awk

rwxrwxr‑x 1 root root 1054 Apr 20 19:37 belts.awk

Для нахождения всех файлов, которые обновлялись позже, чем age.awk, но раньше, чем belts.awk, выполните следующую команду (применение опции -exec описано чуть ниже):

$ find . — newer age.awk! — newer beIt*.awk -exec ls -l {} \;


-rwxrwxr‑x 1 root root 62 Apr 18 11:32 . /who.awk

-rwxrwxr‑x 1 root root 4 9 Apr 18 12:05 ./group.awk

-rw‑r--r- 1 root root 201 Apr 20 19:30 ./grade2.txt

-rwxrwxr‑x 1 root root 1054 Apr 20 19:37 ./belts.awk

Ho как быть, если необходимо найти файлы, созданные, скажем, в течение последних двух часов, а у вас нет файла, сформированного ровно два часа назад, с которым можно было бы сравнивать? Создайте такой файл! Для этой цели предназначена команда touch -t, которая создает файл с заданной временной меткой в формате ММДДччмм (месяц–день–часы–минуты). Например:

$ touch -t 05042140 dstamp

$ ls -l dstamp

-rw‑r—r— I dave admin 0 May 4 21:40 dstamp

В результате будет получен файл, дата создания которого — 4 мая, время создания —21:40 (предполагается, что текущее время — 23:40). Теперь можно применить

команду find с опцией -newer для нахождения всех файлов, которые обновлялись в течение последних двух часов:

$ find . — newer dstamp -print

2.1.8. Опция -type

Операционные системы UNIX и Linux поддерживают различные типы файлов (см. главу 1). Поиск файлов нужного типа осуществляется посредством команды, find с опцией -type. Например, для нахождения всех подкаталогов в каталоге /etc воспользуйтесь такой командой:

$ find /etc -type d -print

Чтобы получить список всех файлов, но не каталогов, выполните следующую команду:

$ find . ! — type d -print

Ниже приведена команда, которая предназначена для поиска всех символических ссылок в каталоге /etc.

$ find /etc -type l -print

2.1.9. Опция -size

В процессе поиска размер файла указывается с помощью опции -size n, где N -pазмер файла в блоках по 512 байтов. Возможные аргументы имеют следующие значения:

+N — поиск файлов, размер которых больше заданного,

— N — меньше заданного,

N -pавен заданному.

Если в аргументе дополнительно указан символ 'c', то размер считается заданным в байтах, а не в блоках, а если символ к — в килобайтах.

Для поиска файлов, размер которых превышает 1 Мб, предназначена команда

$ find . — size +1000k -print

Следующая команда выполняет поиск в каталоге /home/apache файлов, размер которых в точности равен 100 байтам:

$ find /home/apache -size 100c -print

Произвести поиск файлов, размер которых превышает 10 блоков (5120 байтов), позволяет приведенная ниже команда:

$ find . — size +10 -print

2.1.10. Опция -depth

Опция -depth позволяет организовать поиск таким образом, что сначала проверяются все файлы текущего каталога (и рекурсивно все его подкаталоги) и только в конце — запись самого каталога. Эта опция широко применяется при создании списка файлов, помещаемых в архив на магнитной ленте с помощью команды cpio или tar, так как в этом случае сначала записывается на ленту образ каталога и лишь после этого задаются права доступа к нему. Это позволяет пользователю архивировать те каталоги, для которых у него нет разрешения на запись.

Следующая команда выводит список всех файлов и подкаталогов текущего каталога:

$ find . — name "*" — print -о -name ".*" — print -depth

Вот как могут выглядеть результаты ее работы:

./.Xdefaults

./.bash_logout

./.bash_proflie

./.bashrc

./.bash_history

./file

./Dir/file1

./Dir/file2

./Dir/file3

./Dir/Subdir/file4

./Dir/Subdir

./Dir

2.1.11. Опция -mount

Поиск файлов только в текущей файловой системе, исключая другие смонтированные файловые системы, обеспечивает опция -mount команды find . В следующем примере осуществляется поиск всех файлов с расширением хс в текущем разделе диска:

$ find / -name "*.XC" — mount -print

2.1.12. Поиск файлов с последующей архивацией командой cpio

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

Вот как выполняется запись на магнитную ленту содержимого каталогов /etc, /home и /apps:

$ cd /

$ find etc home apps -depth -print | cpio -ov > dev/rmt0

Опция -o команды cpio задает режим записи файлов на ленту. Опция -v (verbose -cловесный режим) является указанием команде cpio сообщать о каждом обрабатываемом файле.

Обратите внимание на то, что в именах каталогов отсутствует начальный символ '/'. Таким образом задаются относительные путевые имена архивируемых каталогов, что при последующем чтении файлов из архива позволит воссоздавать их в любой части операционной системы, а не только в корневом каталоге.

2.1.13. Опции -exec и -ok

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

ls -l). Многие пользователи применяют опцию -exec для нахождения старых файлов, подлежащих удалению. Я рекомендую вместо команды rm выполнить сначала команду ls, чтобы убедиться в том, что команда find нашла именно те файлы, которые нужно удалить.

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

$ find . — type f -exec ls -1 {} \;

-rwxr‑xr‑x 10 root wheel 1222 Jan 4 1993 ./sbin/C80
-rwxr‑xr‑x 10 root wheel 1222 Jan 4 1993 ./sbin/Normal
-rwxr‑xr‑x 10 root wheel 1222 Jan 4 1993 ./sbin/Revvid
Здесь выполняется поиск обычных файлов, список которых отображается на экране с помощью команды ls -l.

Чтобы найти файлы, которые не обновлялись в каталоге /logs в течение последних пяти дней, и удалить их, выполните следующую команду:

$ find /logs -type f -mtime +5 -exec rm {} \;

Следует соблюдать осторожность при перемещении и удалении файлов. Пользуйтесь опцией -ok, которая позволяет выполнять команды mv и rm в безопасном режиме (перед обработкой очередного файла выдается запрос на подтверждение). В следующем примере команда find находит файлы с расширением LOG, и если какой‑то файл создан более пяти дней назад, она удаляет его, но сначала просит вас подтвердить эту операцию:

$ find . — name "*.LOG" — mtime +5 -ok rm {} \;

< rm… ./nets. LOG > ? у

Для удаления файла введите у, а для предотвращения этого действия — n.

2.1.14. Дополнительные примеры использования команды find

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

$ find ~ -print

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

$ find . — type f -perm +4000 -print

Чтобы получить список пустых файлов, воспользуйтесь такой командой:

$ find / -type f -size 0 -exec ls -l {} \;

В одной из моих систем каждый день создается системный журнал аудита. К имени журнального файла добавляется номер, что позволяет сразу определить, какой файл создан позже, а какой -pаньше. Например, версии файла admin.log нумеруются последовательно: admin.log.001, admin.log. O02 и т. д. Ниже приведена команда find, которая удаляет все файлы admin.log, созданные более семи дней назад:

$ find /logs -name 'admin.log. [0-9] [0-9][О-9] ' — atime +7 exec \ rm {} \;

2.2. Команде xargs

При наличии опции -exec команда find передает указанной команде все найденные файлы, которые обрабатываются за один раз. К сожалению, в некоторых системах длина командной строки ограниченна, поэтому при обработке большого числа файлов может быть выдано сообщение об ошибке, которое обычно гласит: "Too many arguments" (слишком много аргументов) или "Arguments too long" (слишком большой список аргументов). В этой ситуации на помощь приходит команда xargs. файлы, полученные от команды find, она обрабатывает порциями, а не все сразу.

Рассмотрим пример, в котором команда find возвращает список всех файлов, имеющихся в системе, а команда xargs выполняет для них команду file, проверяющую тип каждого файла:

$ find / -type f -print | xargs file

/etc/protocols: English text /etc/securetty: ASCII text

Ниже приведен пример, демонстрирующий поиск файлов дампа, имена которых команда echo помешает в файл /tmp/core.log.

$ find / -name core -print | xargs echo > /tmp/core.log

В следующем примере в каталоге /apps/audit выполняется поиск всех файлов, к которым другие пользователи имеют полный доступ. Команда chmod удаляет для них разрешение на запись:

$ find /apps/audit -perm -7 -print | xargs chmod o‑w

Завершает наш перечень пример, в котором команда grep ищет файлы, содержащие слово "device":

$ find / -type f -print | xargs grep "device"

2.3. Заключение

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

ГЛАВА 3

Выполнение команд в фоновом режиме

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

В этой главе рассматриваются следующие темы:

   • планирование заданий с помощью программы cron;

   • планирование заданий с помощью команды at;

   • выполнение заданий в фоновом режиме;

   • выполнение заданий с помощью команды nohup.


cron Системный планировщик, применяемый для многократного выполнения заданий в указанные периоды времени; является демоном, т. е. работает только в фоновом режиме
at Команда, которая служит для однократного выполнения заданий в назначенное время
& Оператор, позволяющий перевести задание в фоновый режим
nohup Команда для перевода задания в фоновый режим таким образом, чтобы оно не реагировало на сигнал HUP (hang‑up -oтбой) и продолжало выполняться, даже если запустивший его пользователь выйдет из системы

3.1. Планировщик cron и команда crontab

Программа cron является основным системным планировщиком, служащим для выполнения различных заданий в фоновом режиме. Команда crontab позволяет пользователям создавать, редактировать и удалять инструкции для программы cron посредством специального crontab–файла. У каждого пользователя может быть свой crontab–файл, но в крупных системах администратор (пользователь root) обычно исключает данную возможность. В этом случае администратор создает вспомогательные файлы cron.deny и cron.allow, содержащие списки пользователей, которым соответственно запрещено и разрешено выполнять команду crontab.

3.1.1. Структура crontab–файла

Чтобы планировать выполнение заданий в определенное время, нужно знать формат записей в crontab–файле. Каждая запись содержит шесть полей;


1 Минуты — 0—59
2 Часы — 0—23 (0 означает полночь)
3 День месяца — 1—31
4 Месяц — 1—12
5 День недели — 0—7 {0 и 7 означает воскресенье)
6 Команда, которая должна быть выполнена
Общий формат записи таков:

минуты часы день_месяца месяц деиь_нвдели команда

Все поля разделяются пробелами.

В первых пяти полях записи могут быть указаны диапазоны значений. Например, для того чтобы обеспечить выполнение задания с понедельника по пятницу, надлежит указать в пятом поле значение 1-5,

Допускается также задание списка значений, разделенных запятыми. Если,

например, задание должно быть выполнено только в понедельник и четверг, следует

ввести 1, 4.

Символ звездочки (*) — это обозначение диапазона "от первого до последнего", т. е. каждую минуту, каждый день и т. д. Если указан диапазон, то можно задать для него шаг пропуска с помощью символа /. Например, запись */2 означает "каждый второй".

В crontab–файле допускаются комментарии. В начале строки комментария должен стоять символ #.

3.1.2. Примеры записей в crontab–файле

Запись

30 21 * * * /apps/bin/cleanup.sh

означает выполнение сценария cteanup.sh в каталоге /apps/bin каждый вечер в 21:30. Запись

45 4 1,10,22 * * /apps/bin/backup.sh

означает выполнение сценария backup.sh в каталоге /apps/bin в 4:45 утра 1–го, 10–го и 22–го числа каждого месяца. Запись

10 1 * * 6,0 /bin/find -name "core" — exec rm {} \;

означает выполнение команды find для удаления файлов дампа в 1:10 ночи по субботам и воскресеньям. Запись

0,30 18-23 * * * /apps/bin/dbcheck.sh

означает выполнение сценария dbchecksh в каталоге /apps/bin каждые полчаса между 18:00 и 23:00.

Запись

0 23 * * 6 /apps/bin/qtrend.sh

означает выполнение сценария qtrend.sh в каталоге /apps/bin в 23:00 каждую субботу. При выполнении команд и сценариев, указанных в crоntab–файле, следует убедиться, что корректно заданы все необходимые переменные среды. Программа cron не сделает это за вас: это не входит в ее компетенцию. Поэтому локальные переменные среды должны быть установлены вручную, в отличие от глобальных переменных, которые устанавливаются автоматически. Данная задача может быть решена непосредственно в crontab–файле за счет создания записи следующего вида:

имя_переменной=значение

Если программа cron не сможет выполнить поступившую команду, пользователь получит электронное сообщение, в котором будут указаны причины неудачи.

3.1.3. Опции команды crontab

Общий формат команды crontab таков:

crontab [-u пользователь] — e -l -r


ОПЦИЯ назначение
-u пользователь Установка имени пользователя, для которого нужно создать
crontab–файл
-e Активизация режима редактирования crontab–файла
-1 Отображение содержимого crontab–файла
-r Удаление crontab–файла
Если вы хотите работать с собственным crontab–файлом, то указывать опцию — и нет необходимости.

3.1.4. Создание crontab–файла

Сначала, еще до того, как crontab–файл будет помещен в очередь заданий программы cron, необходимо установить переменную среды editor. Благодаря этому планировщик получит указание относительно того, какой редактор следует использовать при обработке crontab–файлов. Если вы предпочитаете редактор vi, откройте файл .profile или .bash_profile, находящийся в вашем начальном каталоге, и поместите в него следующие команды:

EDITOR=vi; export EDITOR

Далее создайте новый файл <имя_полъзователя>cron, где <имя_польэователя> — ваше регистрационное имя. Вот пример содержимого такого файла:

   • вывод текущей даты на экран

   • каждые 15 минут между 18:00 и 6:00

0,15,30,45 18-06 * * * /bin/echo 'date' > /dev/console

Приведенная выше запись задает отображение на экране текущей даты каждые 15 минут в указанном интервале времени. Теперь, если система вдруг "зависнет", вы сможете определить, когда это произошло.

Чтобы поместить в очередь заданий планировщика cron свой crontab–файл, выполните команду crontab, указав в ней имя созданного файла:

$ crontab davecron

Копия файла будет помещена в каталог /var/spool/cron, а имя копии совпадет с вашим регистрационным именем (в данном случае — dave).

3.1.5. Вывод на экран содержимого crontab–файла

Для вывода на экран содержимого crontab–файла предназначена команда crontab -l:

$ crontab -l

#(davecron installed on Tue Kay 4 13:07:43 1999)

#вывод текущей даты на экран

#каждые 15 минут между 18:00 и 6:00

0,15,30,45 18-06 * * * /bin/echo "date" > /dev/console

Вот как легко можно создать резервную копию crontab–файла в своем начальном каталоге:

$ crontab -1 > $HOME/davecron

3.1.6. Редактирование crontab–файла

Для добавления, редактирования или удаления записей в crontab–файле используется тот редактор, который указан в переменной среды editor. Чтобы отредактировать файл, выполните команду

$ crontab -e

При сохранении файла программа cron проверяет значения полей и информирует пользователя об обнаруженных ошибках. Если какая‑либо запись содержит ошибку, файл не будет принят.

В процессе редактирования crontab–файла можно добавлять в него новые записи. Добавим, например, следующую запись:

   • удаление файлов дампа в 3.30 утра в 1–й, 7–й, 14–й,

   • 21–й и 2б–й день каждого месяца

30 3 1,7,14,21,26 * * /bin/find -name "core" — exec rm {} \;

Желательно размещать перед каждой записью комментарий, объясняющий ее назначение.

Теперь сохраним файл, выйдем из редактора и проверим результат:

$ crontab -1

#(davecron installed on Tue May 4 13:07:43 1999)

#вывод текущей даты на экран

#каждые 15 минут между 18:00 и 6:00

0,15,30,45 18-06 * * * /bin/echo "date" > /dev/console

#удаление файлов дампа в 3.30 утра в 1–й, 7–й, 14–й,

#21–й и 26–й день каждого месяца

30 3 1,7,14,21,26 * * /bin/find -name "core" — exec rm {} \;

3.1.7. Удаление crontab–файла

Для удаления своего crontab–файла введите команду $ crontab -r

3.1.8. Восстановление утерянного crontab–файла

Если crontab–файл случайно удален, инсталлируйте заново исходный файл из вашего начального каталога:

$ crontab <имя_файла>

Именно по этой причине в документации к программе cron говорится о том, что не рекомендуется прибегать к непосредственному редактированию crontab–файла. Следует вносить все изменения в копию файла и инсталлировать ее заново.

3.2. Команда at

Команда at позволяет передавать задания демону cron для одноразового выполнения в назначенное время. Выдавая задание, команда at сохраняет в отдельном файле как его текст, так и все текущие переменные среды. Заметим, что команда crontab не делает этого. По умолчанию все результаты выполнения задания направляются пользователю в виде электронного сообщения.

Как и в случае с программой cron, пользователь root может контролировать, кому разрешено или запрещено выполнять команду at. Соответствующие списки пользователей содержатся в файлах at.allow и at.deny, находящихся в каталоге /etc.

Базовый формат команды at таков:

at [-f файл] [-l -d -m] время


Опция Назначение
-f файл Список заданий должен быть взят из указанного файла
-l Вывод на экран списка заданий, которые ожидают выполнения; аналогична команде atq
-d Удаление задания с указанным номером; аналогична команде atrm (в некоторых системах заменяется опцией -r)
-m Выдача пользователю электронного сообщения о завершении задания
время Спецификация времени, когда будет выполнено задание. Эта спецификация может быть довольно сложной. Допускается указание не только времени в формате часы: минуты, но и даты, а также многочисленных ключевых слов, таких как названия дней недели, месяцы, наречий today (сегодня), tomorrow (завтра), now (сейчас) и др. Наиболее удобна запись вида now + 3 hours (через три часа).

3.2.1. Запуск команд и сценариев с помощью команды at

Текст задания можно передать команде at двумя способами: в файле или в режиме командной строки at. Если задание состоит из одной команды или двух — трех команд, объединенных каналом, то удобнее воспользоваться вторым способом. Для запуска сценариев интерпретатора shell предпочтительнее первый вариант.

В случае необходимости выполнить одиночную команду вызовите команду at, указав требуемое время. Отобразится приглашение at>. Введите свою команду, а затем нажмите [Enter] и [Ctrl+D]. Рассмотрим пример.

$ at 21:10

at> find / -name "passwd" — print

at> <EOT>

warning: commands will be executed using /bin/sh job 1 at 1999-05-05 21:10

Запись <ЕОТ> появляется после нажатия [Ctrl+D]. Теперь в 21:10 будет выполнена команда find, ищущая в системе файлы с именем passwd. Обратите внимание на то, что команда at присваивает заданию уникальный идентификатор 1. Результаты выполнения команды find будут направлены вам по электронной почте. Вот фрагмент соответствующего электронного сообщения:

Subject: Output from your job 1

/etc/passwd

/etс/pam.d/passwd

/etc/uucp/passwd

/tmp/passwd

/root/passwd

/usr/bin/passwd

/usr/doc/uucp-1.06.1/sample/passwd

Ниже приведены примеры корректного указания времени при вызове команды at:

at 6.45am May 12 — 12–го мая в 6:45 утра

at 11.10pm — в 23:10 (сегодня или завтра, если

это время уже прошло)

at now + 1 hour — через час at 9am tomorrow — завтра в 9:00 утра

at 15:00 May 24 — 24 мая в 15:00 at 4am + 3 days — через 3 дня в 4:00 утра

Если необходимо запустить с помощью команды at файл сценария, укажите его имя после опции -f, как это сделано ниже:

$ at 3.00pm tomorrow -f /apps/bin/db_table.sh

warning: commands will be executed using /bin/sh job 8 at 1999-05-06 15:00

Сценарий db_table.sh будет выполнен завтра в 15:00. Передать задание команде at позволяет также команда echo? $ echo find /etc -name "passwd" — print | at now +1 minute

3.2.2. Просмотр списка запланированных заданий

Для того чтобы просмотреть полный список запланированных заданий, введите команду at -l или atq:

$ atq

   1. 1999-05-05 23:00 а

   2. 1999-05-06 06:00 а

   3. 1999-05-21 11:20 а

В первом столбце содержится идентификатор заданния, за ним следуют дата и время выполнения задания. В последнем столбце находится символ а, указывающий на то, что задание получено от команды at. Существует также команда batch, которая планирует выполнение задания в период наименьшей загруженности системы. Задания, полученные от этой команды, помечаются в выводе команды atq символом b.

Получив задание, команда at создает в каталоге /var/spoot/at файл, в который помещает текст задания и заносит текущие установки всех переменных среды:

$ pwd

/var/spool/at

$ ls

a0000200eb7ae4 a0000400ebd228 a0000800eb7ea4 spool

3.2.3. Удаление запланированного задания

Для удаления задания предназначена команда atrm (синоним команды at -d или at -r), имеющая следующий формат:

atrm номер_задания

Чтобы удалить задание, нужно сначала получить его идентификатор. Поэтому сначала введите команду at -1 и узнайте идентификатор интересующего вас задания, а затем выполните команду atrm:

$ at -l

   1. 1999-05-05 23:00 а

   2. 1999-05-06 06:00 а

   3. 1999-05-21 11:20 а

$ atrm 3

$ at -l

2 1999-05-05 23:00 а

4 1999-05-21 11:20 а

3.3. Оператор &

При выполнении задания в экранном режиме происходит "захват" терминала на весь этот период. Перевод задания в фоновый режим позволяет освободить терминал для других целей. Чтобы выполнить команду в фоновом режиме, укажите после нее оператор &:

команда &

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

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

команда > выходной файл 2>&1 &

Данная конструкция задает переадресацию стандартных потоков вывода и ошибок в указанный файл.

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

3.3.1. Запуск команды в фоновом режиме

Выполним в фоновом режиме команду find, которая ищет в каталоге /etc файл srm.conf, и перенаправим ее вывод в файл find .dt

$ find /etc -name "srm.conf" — print > find .dt 2>&1 &

[1] 27015

Номер процесса в данном случае равен 27015. После завершения выполнения задания, когда вы в очередной раз нажмете клавишу [Return], на экране отобразится такое сообщение:

[1]+ Done find /etc "srm.conf" — print

3.3.2. Получение списка выполняющихся процессов с помощью команды ps

Предположим, имеется сценарий psl, который выполняется довольно долго: $ p$1 &

[2] 28305

Узнать о состоянии этого задания можно с помощью команды ps, которая по умолчанию выводит список всех запущенных в данный момент процессов, принадлежащих текущему пользователю:


$ ps
PID TTY TIME CMD
679 pts/0 00:00:01 bash
28305 pts/0 00:02:07 psl
28310 pts/0 00:00:00 ps
Здесь в четырех столбцах приведена следующая информация: первый — идентификатор процесса, второй — идентификатор терминала, с которого он запущен, третий -cуммарное время использования процессора, четвертый — выполняемая команда.

Если процессов слишком много, воспользуйтесь командой grep, указав в ней номер нужного задания:

$ ps | grep 28305

28305 pts/0 00:02:20 psl

Обратите внимание: команда ps не показывает, в каком режиме выполняется задание — в фоновом или экранном.

3.3.3. Уничтожение фонового задания

Сигнал о завершении посылается процессу командой kill:

kill [-сигнал] номер_процесса

Далее в этой книге мы рассмотрим, какие существуют сигналы. Пока же достаточно знать, что по умолчанию команда kill посылает сигнал номер 1 — HUP (hang‑up -oтбой). На экран выводится сообщение о прекращении задания:

$ kill 28305

[1]+ Terminated ./psl

Многие команды и сценарии перехватывают сигнал HUP, поэтому команда kill -1 не уничтожает их. В этом случае нужно воспользоваться командой kill -9, которая посылает процессу сигнал KILL (уничтожить). Этот сигнал не перехватывается и означает безусловное уничтожение процесса.

$ kill -9 28305

[1] + Killed ./psl

3.4. Команда nohup

Задание, выполняющееся в фоновом режиме, уничтожается, когда запустивший его пользователь выходит из системы. Вы можете обеспечить, чтобы после завершения сеанса работы в системе продолжилось автономное выполнение вашего задания. Для этого запустите его с помощью команды nohup. Общий формат этой команды таков:

nohup команда &

3.4.1. Запуск задания с помощью команды nohup

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

nohup команда > выходной файл 2>&1 &

'Давайте проверим работу команды nohup на примере упомянутого выше сценария psl.

$ nohup psl &

[1] 179

nohup; appending output to 'nohup.out'

Теперь выйдите из интерпретатора shell, выполнив команду logout, снова зарегистрируйтесь и введите следующую команду:

$ ps x | grep psl

30004 ? RN 4:01 sh ./psl

30006 pts/1 S 0:00 grep psl

Опция x предназначена для вывода списка заданий, не связанных с терминалом (обратите внимание на знак вопроса во втором столбце). В третьем столбце указан статус задания. Статус R означает, что процесс выполняется, статус N — это признак снижения

приоритета у выполняемого процесса. В четвертом столбце приведено суммарное время использования процессора. Как видите, сценарий продолжает свою работу.

Если система не поддерживает команду ps x, воспользуйтесь опцией -e, которая предназначена для получения списка всех системных процессов:

$ ps -e | grep psl

30004 ? 00:04:01 sh ./psl

3.4.2. Одновременный запуск нескольких заданий

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

cat /home/acccmnts/qtr_04 99 | /apps/bm/trials.awk | sort | lp

Поместим ее в файл:

$ cat > quarterend

cat /home/accounts/qtr_0499 | /apps/bin/trials.awk | sort | lp <CTRL‑D>

Сделаем файл исполняемым:

$ chmod 744 quarterend ...



Все права на текст принадлежат автору: Дэвид Тейнсли.
Это короткий фрагмент для ознакомления с книгой.
Linux и UNIX: программирование в shell. Руководство разработчика.Дэвид Тейнсли