Выбрать главу

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

Результаты

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

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

$ unrm

Contents of your deleted files archive (sorted by date):

··detritus··················this is a test

··detritus··················garbage

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

Листинг 2.9. При запуске с единственным аргументом сценарий unrm попытается восстановить файл

$ unrm detritus

More than one file or directory match in the archive:

··1) detritus (size = 7688Kb, deleted = 11/29 at 10:00:12)

··2) detritus (size = 4Kb, deleted = 11/29 at 09:59:51)

Which version of detritus should I restore ('0' to quit)? [1]: 0

unrm: Restore canceled by user.

Усовершенствование сценария

Используйте этот сценарий внимательно, потому что в нем не выполняется никаких проверок и отсутствуют всякие ограничения. Объем архива с удаленными файлами будет расти без всяких ограничений. Чтобы избежать исчерпания дискового пространства, создайте задание для cron, вызывающее команду find, для очистки удаленных файлов, с флагом −mtime, чтобы выявить файлы, остававшиеся невостребованными в течение нескольких недель. 14-дневного срока хранения в архиве, вероятно, будет вполне достаточно и для большинства пользователей, и для того, чтобы предотвратить исчерпание дискового пространства.

Можно также внести ряд других усовершенствований, которые сделают сценарий более дружественным для пользователя. Например, добавить флаг −l для восстановления последней (latest) копии и флаг−D для удаления дополнительных копий файла. Подумайте, какие еще флаги вы добавили бы, чтобы упростить работу со сценарием?

№ 17. Журналирование операций удаления файлов

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

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

ПРИМЕЧАНИЕ

Обертки — мощная концепция, и в этой книге вы еще не раз встретитесь с ней.

Код

Листинг 2.10. Сценарий logrm

··#!/bin/bash

··# logrm — журналирует все операции удаления файлов, если вызывается без флага −s

··removelog="/var/log/remove.log"

··if [$# −eq 0]; then

····echo "Usage: $0 [-s] list of files or directories" >&2

····exit 1

··fi

··if ["$1" = "-s"]; then

····# Запрошена операция без журналирования…

····shift

··else

····echo "$(date): ${USER}: $@" >> $removelog

··fi

··/bin/rm "$@"

··exit 0

Как это работает

Первая условная инструкция в проверяет ввод пользователя и показывает сообщение, описывающее порядок использования сценария, если он вызван без аргументов. Затем, в строке , сценарий проверяет, не содержит ли аргумент $1 флаг −s; если содержит, сценарий пропустит операцию журналирования. В заключение сценарий записывает текущее время, имя пользователя и текст команды в файл $removelog , и передает свои параметры фактической программе /bin/rm .

Запуск сценария

Обычно при установке программ-оберток, таких как сценарий logrm, обертываемые команды переименовываются, а оберткам присваиваются имена оригинальных команд. Если вы решите пойти этим путем, убедитесь, что обертка вызывает переименованную программу, а не саму себя! Например, если вы переименовали /bin/rm в /bin/rm.old, а сценарий сохранили с именем /bin/rm, тогда в предпоследней строке сценария замените вызов /bin/rm на /bin/rm.old.