Добавить в цитаты Настройки чтения

Страница 103 из 113

                                        ;;

                                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>

                        <P>$TIME_STAMP</P>

                        $(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: Ca

                exit 1

        fi

else

        write_html_page

fi

Код, обслуживающий логику параметра -f, находится в конце листинга, приведенного выше. Он проверяет, определено ли имя файла и затем — доступность для записи файла с указанным именем. Для этого выполняется команда touch с последующей проверкой, что файл является обычным файлом. Эти две проверки позволяют обработать ситуацию неправильно указанного пути (в этом случае touch потерпит неудачу) и убедиться, что существующий файл является обычным файлом.

Как видите, функция write_html_page вызывается, чтобы сгенерировать фактическое содержимое страницы, которое затем либо выводится в стандартный вывод (если переменная filename содержит пустое значение), либо перенаправляется в указанный файл.

Заключительное замечание

С помощью дополнительных позиционных параметров мы можем теперь писать довольно функциональные сценарии. Позиционные параметры помогают создавать очень полезные функции командной оболочки для выполнения повседневных задач, которые можно поместить в файл .bashrc.

Наша программа sys_info_page выросла и усложнилась. Ниже приводится полный листинг программы с выделенными последними изменениями:

#!/bin/bash

# sys_info_page: программа вывода страницы с информацией о системе

PROGNAME=$(basename $0)

TITLE="System Information Report For $HOSTNAME"

CURRENT_TIME=$(date +"%x %r %Z")

TIME_STAMP="Generated $CURRENT_TIME, by $USER"

report_uptime () {

        cat <<- _EOF_

                <H2>System Uptime</H2>

                <PRE>$(uptime)</PRE>

                _EOF_

        return

}

report_disk_space () {

        cat <<- _EOF_

        <H2>Disk Space Utilization</H2>

        <PRE>$(df -h)</PRE>

        _EOF_

        return

}

report_home_space () {

        if [[ $(id -u) -eq 0 ]]; then

                cat <<- _EOF_

                        <H2>Home Space Utilization (All Users)</H2>



                        <PRE>$(du -sh /home/*)</PRE>

                        _EOF_

        else

                cat <<- _EOF_

                        <H2>Home Space Utilization ($USER)</H2>

                        <PRE>$(du -sh $HOME)</PRE>

                        _EOF_

        fi

        return

}

usage () {

        echo "$PROGNAME: usage: $PROGNAME [-f file | -i]"

        return

}

write_html_page () {

        cat <<- _EOF_

        <HTML>

                <HEAD>

                        <TITLE>$TITLE</TITLE>

                </HEAD>

                <BODY>

                        <H1>$TITLE</H1>

                        <P>$TIME_STAMP</P>

                        $(report_uptime)

                        $(report_disk_space)

                        $(report_home_space)

                </BODY>

        </HTML>

        _EOF_

         return

}

# обработка параметров командной строки

interactive=

filename=

while [[ -n $1 ]]; do

        case $1 in

                -f | --file)            shift

                                        filename=$1

                                        ;;

                -i | --interactive)     interactive=1

                                        ;;

                -h | --help)            usage

                                        exit

                                        ;;

                *)                      usage >&2

                                        exit 1

                                        ;;

        esac

        shift

done

# интерактивный режим

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

                fi

        done

fi

# вывод страницы html

if [[ -n $filename ]]; then

        if touch $filename && [[ -f $filename ]]; then