··if [$# −eq 0]; then # Позволить 'rm’ вывести сообщение о порядке использования.
····exec $realrm # Our shell is replaced by /bin/rm.
··fi
··# Проверить все параметры на наличие флага '-f’
··flags=""
··while getopts "dfiPRrvW" opt
··do
····case $opt in
······f) exec $realrm "$@"····;; # exec позволяет покинуть сценарий немедленно.
······*) flags="$flags −$opt";; # Другие флаги предназначены команде rm.
····esac
··done
··shift $(($OPTIND — 1))
··# НАЧАЛО ОСНОВНОГО СЦЕНАРИЯ
··# =================
··# Гарантировать наличие каталога $archivedir.
····if [! -w $HOME]; then
······echo "$0 failed: can't create $archivedir in $HOME" >&2
······exit 1
····fi
····mkdir $archivedir
··fi
··for arg
··do
····if [-f "$arg" −o — d "$arg"]; then
······$copy "$arg" "$newname"
····fi
··done
Как это работает
В этом сценарии есть много интересных аспектов, в основном связанных с необходимостью скрыть его работу от пользователя. Например, сценарий не генерирует сообщений об ошибках в ситуациях, когда обнаруживает, что не может продолжить работу; он просто позволяет команде realrm самой сгенерировать такое сообщение, вызывая (обычно) /bin/rm с иногда ошибочными параметрами. Вызов realrm производится с помощью команды exec, которая замещает текущий процесс новым, выполняющим указанную команду. Сразу после вызова команды exec realrm
Поскольку сценарий втайне создает в домашнем каталоге пользователя новый каталог
Наконец, в строке
newname="$archivedir/$(date "+"%S.%M.%H.%d.%m").$(basename "$arg")"
Обратите внимание на использование нескольких элементов $() для формирования нового имени файла. Хотя это немного усложняет сценарий, тем не менее такое решение эффективно. Напомним, что содержимое, заключенное между $(и) выполняется в подоболочке, а результат замещает выражение в скобках.
Но зачем усложнять реализацию добавлением даты и времени в имя резервируемого файла? Чтобы дать возможность сохранять несколько копий удаляемого файла с одним и тем же именем. После архивирования файла сценарием нельзя будет отличить /home/oops.txt от /home/subdir/oops.txt иначе как по времени удаления. Если стирание одноименных файлов произойдет одновременно (или в течение одной секунды), резервные копии файлов, удаленных первыми, будут затерты. Для решения этой проблемы можно организовать добавление абсолютных путей к оригинальным файлам в имена резервных копий.
Запуск сценария
Чтобы установить сценарий, добавьте псевдоним — тогда при вводе команды rm действительно будет вызываться этот сценарий, а не команда /bin/rm. В командных оболочках bash и ksh псевдонимы определяются так:
alias rm=yourpath/newrm
Результаты
Результаты работы этого сценария преднамеренно скрыты (как показывает листинг 2.6), так что обратим все внимание на каталог
Листинг 2.6. Тестирование сценария newrm
$ ls ~/.deleted-files