Искусство программирования на языке сценариев командной оболочки - Мендель Купер
Шрифт:
Интервал:
Закладка:
exit 0
Скобочная нотация позиционных параметров дает довольно простой способ обращения к последнему аргументу, переданному в сценарий из командной строки. Такой способ подразумевает использование косвенной адресации.
args=$# # Количество переданных аргументов.
lastarg=${!args} # Обратите внимание: lastarg=${!$#} неприменимо.
В сценарии можно предусмотреть различные варианты развития событий, в зависимости от имени сценария. Для этого сценарий должен проанализировать аргумент $0 -- имя файла сценария. Это могут быть и имена символических ссылок на файл сценария.
Если сценарий ожидает передачи аргументов в командной строке, то при их отсутствии он получит "пустые" переменные, что может вызвать нежелательный побочный эффект. Один из способов борьбы с подобными ошибками -- добавить дополнительный символ в обеих частях операции присваивания, где используются аргументы командной строки.
variable1_=$1_
# Это предотвратит появление ошибок, даже при отсутствии входного аргумента.
critical_argument01=$variable1_
# Дополнительные символы всегда можно "убрать" позднее.
# Это может быть сделано примерно так:
variable1=${variable1_/_/} # Побочный эффект возникает только если имя переменной
# $variable1_ будет начинаться с символа "_".
# Здесь используется один из вариантов подстановки параметров, обсуждаемых в Главе 9.
# Отсутствие шаблона замены приводит к удалению.
# Более простой способ заключается
#+ в обычной проверке наличия позиционного параметра.
if [ -z $1 ]
then
exit $POS_PARAMS_MISSING
fi
---
Пример 4-6. wh, whois выяснение имени домена
#!/bin/bash
# Команда 'whois domain-name' выясняет имя домена на одном из 3 серверов:
# ripe.net, cw.net, radb.net
# Разместите этот скрипт под именем 'wh' в каталоге /usr/local/bin
# Требуемые символические ссылки:
# ln -s /usr/local/bin/wh /usr/local/bin/wh-ripe
# ln -s /usr/local/bin/wh /usr/local/bin/wh-cw
# ln -s /usr/local/bin/wh /usr/local/bin/wh-radb
if [ -z "$1" ]
then
echo "Порядок использования: `basename $0` [domain-name]"
exit 65
fi
case `basename $0` in
# Проверка имени скрипта и, соответственно, имени сервера
"wh" ) whois [email protected];;
"wh-ripe") whois [email protected];;
"wh-radb") whois [email protected];;
"wh-cw" ) whois [email protected];;
* ) echo "Порядок использования: `basename $0` [domain-name]";;
esac
exit 0
---
Команда shift "сдвигает" позиционные параметры, в результате чего парметры "сдвигаются" на одну позицию влево.
$1 <--- $2, $2 <--- $3, $3 <--- $4, и т.д.
Прежний аргумент $1 теряется, но аргумент $0 (имя файла сценария) остается без изменений. Если вашему сценарию передается большое количество входных аргументов, то команда shift позволит вам получить доступ к аргументам, с порядковым номером больше 9, без использования {фигурных скобок}.
Пример 4-7. Использование команды shift
#!/bin/bash
# Использование команды 'shift' с целью перебора всех аргументов командной строки.
# Назовите файл с этим сценарием, например "shft",
#+ и вызовите его с набором аргументов, например:
# ./shft a b c def 23 skidoo
until [ -z "$1" ] # До тех пор пока не будут разобраны все входные аргументы...
do
echo -n "$1 "
shift
done
echo # Дополнительная пустая строка.
exit 0
Команда shift может применяться и к входным аргументам функций. См. Пример 33-10.
Глава 5. Кавычки
Кавычки, ограничивающие строки с обеих сторон, служат для предотвращения интерпретации специальных символов, которые могут находиться в строке. (Символ называется "специальным", если он несет дополнительную смысловую нагрузку, например символ шаблона -- *.)
bash$ ls -l [Vv]*
-rw-rw-r-- 1 bozo bozo 324 Apr 2 15:05 VIEWDATA.BAT
-rw-rw-r-- 1 bozo bozo 507 May 4 14:25 vartrace.sh
-rw-rw-r-- 1 bozo bozo 539 Apr 14 17:11 viewdata.sh
bash$ ls -l '[Vv]*'
ls: [Vv]*: No such file or directory
Некоторые программы и утилиты могут вызываться с дополнительными параметрами, содержащими специальными символы, поэтому очень важно предотвратить интерпретацию передаваемых параметров командной оболочкой, позволяя сделать это вызываемой программой.
bash$ grep '[Пп]ервая' *.txt
file1.txt:Это первая строка в file1.txt.
file2.txt:Это Первая строка в file2.txt.
Примечательно, что "не окавыченный" вариант команды grep [Пп]ервая *.txt будет правильно исполняться в Bash, но не в tcsh.
Вообще, желательно использовать двойные кавычки (" ") при обращении к переменным. Это предотвратит интерпретацию специальных символов, которые могут содержаться в именах переменных, за исключением $, ` (обратная кавычка) и (escape -- обратный слэш)[ 14 ]. То, что символ $ попал в разряд исключений, позволяет выполнять обращение к переменным внутри строк, ограниченных двойными кавычками ("$variable"), т.е. выполнять подстановку значений переменных (см. Пример 4-1, выше).
Двойные кавычки могут быть использованы для предотвращения разбиения строки на слова[ 15 ]. Заключение строки в кавычки приводит к тому, что она передается как один аргумент, даже если она содержит пробельные символы - разделители.
variable1="a variable containing five words"
COMMAND This is $variable1 # Исполнение COMMAND с 7 входными аргументами:
# "This" "is" "a" "variable" "containing" "five" "words"
COMMAND "This is $variable1" # Исполнение COMMAND с одним входным аргументом:
# "This is a variable containing five words"
variable2="" # Пустая переменная.
COMMAND $variable2 $variable2 $variable2 # Исполнение COMMAND без аргументов.
COMMAND "$variable2" "$variable2" "$variable2" # Исполнение COMMAND с 3 "пустыми" аргументами.
COMMAND "$variable2 $variable2 $variable2" # Исполнение COMMAND с 1 аргументом (и 2 пробелами).
# Спасибо S.C.
Заключение в кавычки аргументов команды echo необходимо только в том случае, когда разбиение на отдельные слова сопряжено с определенными трудностями.
Пример 5-1. Вывод "причудливых" переменных
#!/bin/bash
# weirdvars.sh: Вывод "причудливых" переменных
var="'(]\{}$""
echo $var # '(]{}$"
echo "$var" # '(]{}$" Никаких различий.
echo
IFS=''
echo $var # '(] {}$" символ-разделитель преобразован в пробел.
echo "$var" # '(]{}$"
# Примеры выше предоставлены S.C.
exit 0
Одиночные кавычки (' ') схожи по своему действию с двойными кавычками, только не допускают обращение к переменным, поскольку специальный символ "$" внутри одинарных кавычек воспринимается как обычный символ. Внутри одиночных кавычек, любой специальный символ, за исключением ', интерпретируется как простой символ. Одиночные кавычки ("строгие, или полные кавычки") следует рассматривать как более строгий вариант чем двойные кавычки ("нестрогие, или неполные кавычки").
Поскольку внутри одиночных кавычек даже экранирующий () символ воспринимается как обычный символ, попытка вывести одиночную кавычку внутри строки, ограниченной одинарными кавычками, не даст желаемого результата.
echo "Why can't I write 's between single quotes"
echo
# Обходной метод.
echo 'Why can'''t I write '"'"'s between single quotes'
# |-------| |----------| |-----------------------|
# Три строки, ограниченных одинарными кавычками,
# и экранированные одиночные кавычки между ними.
# Пример любезно предоставлен Stephane Chazelas.
Экранирование -- это способ заключения в кавычки одиночного символа. Экранирующий (escape) символ () сообщает интерпретатору, что следующий за ним символ должен восприниматься как обычный символ.
С отдельными командами и утилитами, такими как echo и sed, экранирующий символ может применяться для получения обратного эффекта - когда обычные символы при экранировании приобретают специальное значение.