Основы программирования в Linux - Нейл Мэтью
Шрифт:
Интервал:
Закладка:
Команда return служит для возврата значений из функций, как уже упоминалось ранее при обсуждении функций. Команда принимает один числовой параметр, который становится доступен в сценарии, вызывающем функцию. Если параметр не задан, команда return по умолчанию возвращает код завершения последней команды.
setКоманда set задает переменные-параметры командной оболочки. Она может быть полезна при использовании полей в командах, выводящих значения, разделенные пробелами.
Предположим, что вы хотите использовать в сценарии название текущего месяца. В системе есть команда date, содержащая название месяца в виде строки, но нужно отделить его от других полей. Это можно сделать с помощью комбинации команды set и конструкции $(...), которые обеспечат выполнение команды date и возврат результата (более подробно об этом см. далее). В выводе команды date строка с названием месяца — второй параметр.
#!/bin/sh
echo the date is $(date)
set $(date)
echo The month is $2
exit 0
Программа задает список параметров для вывода команды date и затем использует позиционный параметр $2 для получения названия месяца.
Мы использовали команду date только как простой пример, демонстрирующий, как извлекать позиционные параметры. Поскольку команда date зависит от языковых параметров или локализации, в действительности мы бы извлекли название месяца командой date +%B. У команды date много других вариантов форматирования, более подробную информацию см. на страницах интерактивного справочного руководства к команде.
Команду set можно также применять для передачи параметров командной оболочке и тем самым управления режимом ее работы. Наиболее часто используемый вариант команды set -х, который заставляет сценарий выводить на экран трассировку выполняемой в данный момент команды. Мы обсудим команду set и ее дополнительные опции позже в этой главе, когда будем рассматривать отладку программ.
shiftКоманда shift сдвигает все переменные-параметры на одну позицию назад, так что параметр $2 становится параметром $1, параметр $3 — $2 и т.д. Предыдущее значение параметра $1 отбрасывается, а значение параметра $0 остается неизменным. Если в вызове команды shift задан числовой параметр, параметры сдвигаются на указанное количество позиций. Остальные переменные $*, [email protected] и $# также изменяются в связи с новой расстановкой переменных-параметров.
Команда shift часто полезна при поочередном просмотре параметров, переданных в сценарий, и если вашему сценарию требуется 10 и более параметров, вам понадобится команда shift для обращения к 10-му параметру и следующим за ним.
Например, вы можете просмотреть все позиционные параметры:
#!/bin/sh
while [ "$1" != "" ]; do
echo "$1"
shift
done
exit 0
trapКоманда trap применяется для задания действий, предпринимаемых при получении сигналов, которые подробно будут обсуждаться далее в этой книге. Обычное действие — удалить сценарий, когда он прерван. Исторически командные оболочки всегда использовали числа для обозначения сигналов, но в современных сценариях следует применять имена, которые берутся из файла signal.h директивы #include с опущенным префиксом SIG. Для того чтобы посмотреть номера сигналов и соответствующие им имена, можно ввести в командной строке команду trap -l.
ПримечаниеДля тех, кто не знаком с сигналами, это события, асинхронно посылаемые программе. Стандартно они обычно вызывают прекращение выполнения программы.
С помощью команды trap передается предпринимаемое действие, за которым следует имя (имена) сигнала для перехвата:
trap команда сигнал
Напоминаем, что обычно сценарии обрабатываются интерпретатором сверху вниз, поэтому вы должны задать, команду trap перед той частью сценария, которую хотите защитить.
Для возврата к стандартной реакции на сигнал, просто задайте команду как -. Для игнорирования сигнала задайте в команде пустую строку ''. Команда trap без параметров выводит текущий список перехватов и действий.
В табл. 2.9 перечислены самые важные, включенные в. стандарт Х/Open сигналы, которые можно отследить (со стандартными номерами в скобках). Дополнительную информацию можно найти на страницах раздела 7 интерактивного справочного руководства, посвященного сигналам (man 7 signal).
Таблица 2.9
Сигнал Описание HUP (1) Неожиданный останов; обычно посылается, когда отключается терминал или пользователь выходит из системы INT (2) Прерывание; обычно посылается нажатием комбинации клавиш <Ctrl>+<C> QUIT (3) Завершение выполнения; обычно посылается нажатием комбинации клавиш <Ctrl>+<> ABRT (6) Аварийное завершение; обычно посылается при возникновении серьезной ошибки выполнения ALRM (14) Аварийный сигнал; обычно посылается для обработки превышений лимита времени TERM (15) Завершение; обычно посылается системой, когда она завершает работуА теперь выполните упражнение 2.15.
Упражнение 2.15. Сигналы прерыванийВ следующем сценарии показана простая обработка сигнала.
#!/bin/sh
trap 'rm -f /tmp/my_tmp_file_$$' INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo "press interrupt (CTRL-C) to interrupt..."
while [ -f /tmp/my_tmp_file_$$ ] ; do
echo File exists
sleep 1
done
echo The file no longer exists trap INT
echo creating file /tmp/my_tmp_file_$$
date > /tmp/my_tmp_file_$$
echo "press interrupt (CTRL-C) to interrupt..."
while [ -f /tmp/my_tmp_file_$$ ]; do
echo File exists
sleep 1
done
echo we never get here
exit 0
Если вы выполните этот сценарий, нажимая и удерживая нажатой клавишу <Ctrl> и затем нажимая клавишу <C> (или любую другую прерывающую комбинацию клавиш) в каждом из циклов, то получите следующий вывод:
creating file /tmp/my_tmp_file_141
press interrupt (CTRL-C) to interrupt ...
File exists
File exists
File exists
File exists
The file no longer exists
creating file /tmp/my tmp_file_141
press interrupt (CTRL-C) to interrupt ...
File exists
File exists
File exists
File exists
Как это работает
Сценарий использует команду trap для организации выполнения команды rm -f /tmp/my_tmp_file_$$ при возникновении сигнала INT (прерывание). Затем сценарий выполняет цикл while до тех пор, пока существует файл. Когда пользователь нажимает комбинацию клавиш <Ctrl>+<C>, выполняется команда rm -f /tmp/my_tmp_file_$$, а затем возобновляется выполнение цикла while. Поскольку теперь файл удален, первый цикл while завершается стандартным образом.
Далее сценарий снова применяет команду trap, на этот раз для того, чтобы сообщить, что при возникновении сигнала INT никакая команда не выполняется. Затем сценарий создает заново файл и выполняет второй цикл while. Когда пользователь снова нажимает комбинацию клавиш <Ctrl>+<C>, не задана команда для выполнения, поэтому реализуется стандартное поведение: немедленное прекращение выполнения сценария. Поскольку сценарий завершается немедленно, заключительные команды echo и exit никогда не выполняются.
unsetКоманда unset удаляет переменные или функции из окружения. Она не может проделать это с переменными, предназначенными только для чтения и определенными командной оболочкой, такими как IFS. Команда применяется редко.
В следующем сценарии сначала выводится строка Hello world, а во второй раз новая строка.
#!/bin/sh
foo="Hello World"
echo $foo
unset foo
echo $foo
ПримечаниеНаписание foo= подобно, но не идентично применению команды unset в только что приведенной программе. Оператор foo= задает для переменной foo значение null, но при этом переменная foo все еще существует. Команда unset foo удаляет из окружения переменную foo.