В действительности эта дилемма не имеет надежного решения. Если только речь не идет о создании обертки для run-script или periodic, которая будет знать, как управлять запоминанием времени, чтобы гарантировать невозможность слишком частого запуска заданий. Впрочем, не исключено, что мы вообще зря беспокоимся об этом.
№ 50. Ротация файлов журналов
Пользователи, не имеющие большого опыта использования Linux, могут удивиться, как много команд, утилит и демонов регистрируют события в файлах системных журналов. Даже при наличии больших объемов дискового пространства важно следить за размерами этих файлов и, конечно, их содержимым.
В результате многие системные администраторы предусматривают последовательность команд, которые помещаются в начало утилит, предназначенных для анализа файлов журналов. Пример такой последовательности приведен ниже:
mv $log.2 $log.3
mv $log.1 $log.2
mv $log $log.1
touch $log
Если запускать эту группу команд раз в неделю, в вашем распоряжении всегда будет месячный архив информации из файла журнала, разделенный на порции недельного объема. Однако легко можно создать сценарий, который проделает ту же операцию сразу со всеми файлами журналов в каталоге /var/log , освободив тем самым сценарии анализа от лишнего бремени и организовав ротацию файлов даже в течение месяцев, когда администратор ничего не анализировал.
Сценарий в листинге 6.12 выполняет обход всех файлов в каталоге /var/log , имена которых соответствуют определенному набору критериев, проверяет график ротации каждого подходящего файла и время последнего изменения, чтобы убедиться в необходимости ротации. Если время пришло, сценарий проводит ее.
Листинг 6.12.Сценарий rotatelogs
#!/bin/bash
# rotatelogs — выполняет ротацию файлов журналов в /var/log с целью
#·· архивирования и чтобы предотвратить чрезмерное увеличение файлов
#·· в размерах. Этот сценарий использует файл конфигурации, в котором
#·· можно настроить период ротации каждого файла. Записи в конфигурационном
#·· файле имеют формат logfilename=duration, где duration определяет
#·· количество дней. Если запись в конфигурационном файле для журнала
#·· logfilename отсутствует, rotatelogs будет выполнять ротацию такого
#·· журнала с частотой раз в семь дней. Если для журнала установлена
#·· продолжительность периода ротации, равная нулю, этот журнал будет
#·· игнорироваться сценарием.
logdir="/var/log"····# У вас журналы могут находиться в другом каталоге.
config="$logdir/rotatelogs.conf"
mv="/bin/mv"
default_duration=7·· # По умолчанию ротация выполняется через 7 дней.
count=0
duration=$default_duration
if [! -f $config]; then
··# Файл конфигурации отсутствует? Выйти. Эту проверку можно убрать
··#·· и в отсутствие конфигурационного файла просто использовать настройки
··#·· по умолчанию.
··echo "$0: no config file found. Can't proceed." >&2
··exit 1
fi
if [! -w $logdir −o! −x $logdir]; then
··# −w — право на запись, а −x — право на выполнение. Для создания
··#·· новых файлов в каталогах Unix или Linux необходимы оба. Если
··#·· права отсутствуют, завершить выполнение с выводом сообщения.
··echo "$0: you don't have the appropriate permissions in $logdir" >&2
··exit 1
fi
cd $logdir
# Как бы нам ни хотелось использовать в команде find стандартные обозначения,
#·· такие как: digit:, многие версии find не поддерживают POSIX-совместимые
#·· классы символов — поэтому [0–9].
# Замысловатая команда find подробно обсуждается далее в этом разделе.
#·· Не пропустите, если вам интересно!
for name in $(
find. -maxdepth 1 −type f −size +0c! −name '*[0–9]*' \
····! -name '\.*'! -name '*conf' −print | sed 's/^\.\///')
do
··count=$(($count + 1))
··# Извлечь соответствующую запись из конфигурационного файла.
··duration="$(grep "^${name}=" $config|cut −d= −f2)"
··if [-z "$duration"]; then
····duration=$default_duration # Если совпадений нет, использовать период··································по умолчанию.
··elif ["$duration" = "0"]; then
····echo "Duration set to zero: skipping $name"
····continue
··fi
··# Подготовить имена файлов для ротации. Это просто:
··back1="${name}.1"; back2="${name}.2";
··back3="${name}.3"; back4="${name}.4";
Читать дальше