Чтение онлайн

ЖАНРЫ

Искусство программирования на языке сценариев командной оболочки

Купер Мендель

Шрифт:

Пример 29-7. Трассировка переменной

#!/bin/bash

trap 'echo "VARIABLE-TRACE> $LINENO: \$variable = \"$variable\""' DEBUG

# Выводить значение переменной после исполнения каждой команды.

variable=29

echo "Переменная \"\$variable\" инициализирована числом $variable."

let "variable *= 3"

echo "Значение переменной \"\$variable\" увеличено в 3 раза."

# Конструкция "trap 'commands' DEBUG" может оказаться очень полезной

# при отладке больших и сложных скриптов,

# когда размещение множества инструкций "echo $variable"

# может потребовать достаточно большого времени.

# Спасибо Stephane Chazelas.

exit 0

Конструкция trap '' SIGNAL (две одиночных кавычки) -- запрещает SIGNAL для оставшейся части сценария. Конструкция trap SIGNAL– - восстанавливает действие сигнала SIGNAL. Эти конструкции могут использоваться для защиты критических участков сценария от нежелательного прерывания.

trap '' 2 # Сигнал 2 (Control-C) -- запрещен.

command

command

command

trap 2 # Разрешение реакции на Control-C

Глава 30. Необязательные параметры (ключи)

Необязательные параметры -- это дополнительные ключи (опции), которые оказывают влияние на поведение сценария и/или командной оболочки.

Команда set позволяет задавать дополнительные опции прямо внутри сценария. В том месте сценария, где необходимо, чтобы та или иная опция вступила в силу, вставьте такую конструкцию set -o option-name, или в более короткой форме -- set -option-abbrev. Эти две формы записи совершенно идентичны по своему действию.

#!/bin/bash

set -o verbose

# Вывод команд перед их исполнением.

#!/bin/bash

set -v

# Имеет тот же эффект, что и выше.

Для того, чтобы отключить действие той или иной опции, следует вставить конструкцию set +o option-name, или set +option-abbrev.

#!/bin/bash

set -o verbose

# Вывод команд перед их исполнением.

command

...

command

set +o verbose

# Запретить вывод команд перед их исполнением.

command

# команда не выводится.

set -v

# Вывод команд перед их исполнением.

command

...

command

set +v

# Запретить вывод команд перед их исполнением.

command

exit 0

Как вариант установки опций, можно предложить указывать их в заголовке сценария (в строке sha-bang) -- #!.

#!/bin/bash -x

#

# Далее следует текст сценария.

Так же можно указывать дополнительные ключи в командной строке, при запуске сценария. Некоторые из опций работают только если они заданы из командной строки, например – i– - ключ интерактивного режима работы скрипта.

bash -v script-name

bash -o verbose script-name

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

Таблица 30-1. Ключи Bash

Краткое имя Полное имя Описание
– C noclobber Предотвращает перезапись файла в операциях перенаправления вывода (не распространяется на конвейеры (каналы) -- >|)
– D (нет) Выводит список строк в двойных кавычках, которым предшествует символ $, сам сценарий не исполняется
– a allexport Экспорт всех, определенных в сценарии, переменных
– b notify Выводит уведомление по завершении фоновой задачи (job) (довольно редко используется в сценариях)
– c ... (нет) Читает
команды из ...
– f noglob Подстановка имен файлов (globbing) запрещена
– i interactive Сценарий запускается в интерактивном режиме
– p privileged Сценарий запускается как "suid" (осторожно!)
– r restricted Сценарий запускается в ограниченном режиме (см. Глава 20).
– u nounset При попытке обращения к неопределенным переменным, выдает сообщение об ошибке и прерывает работу сценария
– v verbose Выводит на stdout каждую команду прежде, чем она будет исполнена
– x xtrace Подобна -v, но выполняет подстановку команд
– e errexit Прерывает работу сценария при появлении первой же ошибки (когда команда возвращает ненулевой код завершения)
– n noexec Читает команды из сценария, но не исполняет их (проверка синтаксиса)
– s stdin Читает команды с устройства stdin
– t (нет) Выход после исполнения первой команды
(нет) Конец списка ключей (опций), последующие аргументы будут восприниматься как позиционные параметры.
– - (нет) Эквивалент предыдущей опции (-).

Глава 31. Широко распространенные ошибки

Turandot: Gli enigmi sono tre, la morte una!

Caleph: No, no! Gli enigmi sono tre, una la vita!

Puccini

Использование зарезервированных слов и служебных символов в качестве имен переменных.

case=value0 # Может вызвать проблемы.

23skidoo=value1 # Тоже самое.

# Имена переменных, начинающиеся с цифр, зарезервированы командной оболочкой.

# Если имя переменной начинается с символа подчеркивания: _23skidoo=value1, то это не считается ошибкой.

# Однако... если имя переменной состоит из единственного символа подчеркивания, то это ошибка.

_=25

echo $_ # $_ -- это внутренняя переменная.

xyz((!*=value2 # Вызывает серьезные проблемы.

Использование дефиса, и других зарезервированных символов, в именах переменных.

var-1=23

# Вместо такой записи используйте 'var_1'.

Использование одинаковых имен для переменных и функций. Это делает сценарий трудным для понимания.

do_something

{

echo "Эта функция должна что-нибудь сделать с \"$1\"."

}

do_something=do_something

do_something do_something

# Все это будет работать правильно, но слишком уж запутанно.

Использование лишних пробелов. В отличие от других языков программирования, Bash весьма привередлив по отношению к пробелам.

var1 = 23 # Правильный вариант: 'var1=23'.

# В вышеприведенной строке Bash будет трактовать "var1" как имя команды

# с аргументами "=" и "23".

let c = $a - $b # Правильный вариант: 'let c=$a-$b' или 'let "c = $a - $b"'

if [ $a -le 5] # Правильный вариант: if [ $a -le 5 ]

# if [ "$a" -le 5 ] еще лучше.

# [[ $a -le 5 ]] тоже верно.

Ошибочным является предположение о том, что неинициализированные переменные содержат "ноль". Неинициализированные переменные содержат "пустое" (null) значение, а не ноль.

Поделиться с друзьями: