Шрифт:
filename=$1
;;
– i | --interactive) interactive=1
;;
– h | --help) usage
exit
;;
*) usage >&2
exit 1
;;
esac
shift
done
Сначала мы добавили функцию usage для вывода сообщения, если программа вызывается с параметром --help или с неизвестным параметром.
Затем следует цикл обработки параметров. Цикл продолжается, пока позиционный параметр $1 не получит пустое значение. В конце цикла вызывается команда shift, чтобы сдвинуть позиционные параметры и, в конечном итоге, гарантировать завершение цикла.
Внутри цикла инструкция case проверяет текущий позиционный параметр на соответствие поддерживаемым вариантам. Если данный параметр поддерживается, выполняется соответствующая операция, если нет — выводится сообщение с информацией о правилах пользования программой и сценарий завершается с признаком ошибки.
Обратите внимание, как обрабатывается параметр -f. Обнаружив этот параметр, программа выполняет команду shift, которая сдвинет аргумент параметра -f с именем файла в позиционный параметр $1.
Далее следует код, реализующий интерактивный режим:
# интерактивный режим
if [[ -n $interactive ]]; then
while true; do
read -p "Enter name of output file: " filename
if [[ -e $filename ]]; then
read -p "'$filename' exists. Overwrite? [y/n/q] > "
case $REPLY in
Y|y) break
;;
Q|q) echo "Program terminated."
exit
;;
*) continue
;;
esac
elif [[ -z $filename ]]; then
continue
else
break
fi
done
fi
Если переменная interactive содержит непустое значение, начинается бесконечный цикл, который предлагает ввести имя файла и затем обрабатывает ситуацию, если введенное имя соответствует существующему файлу. Если указанный файл уже существует, пользователю на выбор предлагается три варианта: затереть существующий файл, выбрать другое имя или завершить программу. Если пользователь предпочтет затереть существующий файл, выполняется команда break и цикл прерывается. Обратите внимание, что инструкция case различает только вариант перезаписи существующего файла и завершения программы. Любой другой ответ пользователя будет приводить к переходу в начало цикла с повторным предложением ввести имя файла.
Для поддержки вывода в файл сначала необходимо имеющийся код вывода страницы преобразовать в функцию. Необходимость такого решения станет понятна чуть позже:
write_html_page {
cat <<- _EOF_
<HTML>
<HEAD>
<TITLE>$TITLE</TITLE>
</HEAD>
<BODY>
<H1>$TITLE</H1>
$TIME_STAMP
$(report_uptime)
$(report_disk_space)
$(report_home_space)
</BODY>
</HTML>
_EOF_
return
}
# вывод страницы html
if [[ -n $filename ]]; then
if touch $filename && [[ -f $filename ]]; then
write_html_page > $filename
else
echo "$PROGNAME: Cannot write file '$filename'" >&2
exit 1
fi
else
write_html_page
fi
Код, обслуживающий логику параметра -f, находится в конце листинга, приведенного выше. Он проверяет, определено ли имя файла и затем — доступность для записи файла с указанным именем. Для этого выполняется команда touch с последующей проверкой, что файл является обычным файлом. Эти две проверки позволяют обработать ситуацию неправильно указанного пути (в этом случае touch потерпит неудачу) и убедиться, что существующий файл является обычным файлом.