Если передать сценарию аргумент с именем файла, он попытается восстановить этот файл или каталог (если найдет только одно совпадение) или выведет список найденных кандидатов на восстановление и предложит пользователю выбрать нужную версию файла или каталога.
Результаты
При запуске без аргументов сценарий выведет список всех файлов и каталогов в архиве удаленных файлов, как показано в листинге 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.