
- •Содержание
- •Часть 1. Введение
- •Глава 1. Зачем необходимо знание языка Shell?
- •Глава 2. Для начала о Sha-Bang
- •Часть 2. Основы
- •Глава 3. Служебные символы
- •Глава 4. Переменные и параметры. Введение.
- •Глава 5. Кавычки
- •Глава 6. Завершение и код завершения
- •Глава 7. Проверка условий
- •Глава 8. Операции и смежные темы
- •Часть 3. Углубленный материал
- •Глава 9. К вопросу о переменных
- •Глава 10. Циклы и ветвления
- •Глава 11. Внутренние команды
- •Глава 12. Внешние команды, программы и утилиты
- •Глава 13. Команды системного администрирования
- •Глава 14. Подстановка команд
- •Глава 15. Арифметические подстановки
- •Глава 16. Перенаправление ввода/вывода
- •Глава 17. Встроенные документы
- •Часть 4. Материал повышенной сложности
- •Глава 18. Регулярные выражения
- •Глава 19. Подоболочки, или Subshells
- •Глава 20. Ограниченный режим командной оболочки
- •Глава 21. Подстановка процессов
- •Глава 22. Функции
- •Глава 23. Псевдонимы
- •Глава 24. Списки команд
- •Глава 25. Массивы
- •Глава 26. Файлы
- •Глава 27. /dev и /proc
- •Глава 28. /dev/zero и /dev/null
- •Глава 29. Отладка сценариев
- •Глава 30. Необязательные параметры (ключи)
- •Глава 31. Широко распространенные ошибки
- •Глава 32. Стиль программирования
- •Глава 33. Разное
- •Глава 34. Bash, версия 2
- •Глава 35. Замечания и дополнения
- •Библиография
- •Приложение B. Справочная информация
- •Приложение D. Коды завершения, имеющие предопределенный смысл
- •Приложение F. Системные каталоги
- •Приложение G. Локализация
- •Приложение H. История команд
- •Приложение I. Пример файла .bashrc
- •Приложение J. Преобразование пакетных (*.bat) файлов DOS в сценарии командной оболочки
- •Приложение K. Упражнения
- •Приложение L. Хронология
- •Приложение M. Авторские права
символы, стоящие за строкой-ограничителем, могут дать нежелательные побочные эффекты.
#!/bin/bash
echo "---------------------------------------------------------------------- |
" |
|
cat |
<<LimitString |
|
echo "Это первая строка сообщения во встроенном документе." |
||
echo |
"Это вторая строка сообщения во встроенном документе." |
|
echo |
"Это последняя строка сообщения во встроенном документе." |
|
|
LimitString |
|
#^^^^Отступ перед строкой-ограничителем. Ошибка! |
||
# |
Этот сценарий будет вести себя не так |
как вы ожидаете. |
echo |
"---------------------------------------------------------------------- |
" |
# "Этот комментарий находится за пределами |
'встроенного документа', |
|
#+ и |
не должен выводиться. |
|
echo |
"За пределами встроенного документа." |
|
exit |
0 |
|
echo |
"Держу пари, что эта строка не будет выведена." # Стоит после команды 'exit'. |
Если какая либо задача не может быть решена с помощью "встроенного документа", то вам следует попробовать язык сценариев expect, который приспособлен для передачи параметров на вход интерактивных программ.
Часть 4. Материал повышенной сложности
Итак, мы вплотную подошли к изучению очень сложных и необычных аспектов написания сценариев. В этой части мы попытаемся "сбросить покров тайны" и заглянуть за пределы известного нам мира (представьте себе путешествие по территории, не отмеченной на карте).
Содержание
18.Регулярные выражения
18.1.Краткое введение в регулярные выражения
18.2.Globbing -- Подстановка имен файлов
19.Подоболочки, или Subshells
20.Ограниченный режим командной оболочки
21.Подстановка процессов
22.Функции
22.1.Сложные функции и сложности с функциями
22.2.Локальные переменные
22.2.1.Локальные переменные делают возможной рекурсию.
22.3.Рекурсия без локальных переменных
23.Псевдонимы
24.Списки команд
25.Массивы
26.Файлы
264

27./dev и /proc
27.1./dev
27.2./proc
28./dev/zero и /dev/null
29.Отладка сценариев
30.Необязательные параметры (ключи)
31.Широко распространенные ошибки
32.Стиль программирования
32.1.Неофициальные рекомендации по оформлению сценариев
33.Разное
33.1.Интерактивный и неинтерактивный режим работы
33.2.Сценарии-обертки
33.3.Операции сравнения: Альтернативные решения
33.4.Рекурсия
33.5."Цветные" сценарии
33.6.Оптимизация
33.7.Разные советы
33.8.Проблемы безопасности
33.9.Проблемы переносимости
33.10.Сценарии командной оболочки под Windows
34.Bash, версия 2
Глава 18. Регулярные выражения
Для того, чтобы полностью реализовать потенциал командной оболочки, вам придется овладеть Регулярными Выражениями. Многие команды и утилиты, обычно используемые в сценариях, такие как grep, expr, sed и awk, используют Регулярные Выражения.
18.1. Краткое введение в регулярные выражения
Выражение -- это строка символов. Символы, которые имеют особое назначение, называются метасимволами. Так, например, кавычки могут выделять прямую речь, т.е. быть метасимволами для строки, заключенной в эти кавычки. Регулярные выражения -- это набор символов и/или метасимволов, которые наделены особыми свойствами. [47]
Основное назначение регулярных выражений -- это поиск текста по шаблону и работа со строками.
Звездочка -- * -- означает любое количество символов в строке, предшествующих "звездочке", в
том числе и нулевое число символов.
Выражение "1133*" -- означает 11 + один или более символов "3" + любые другие символы: 113,
1133, 113312, и так далее.
Точка -- . -- означает не менее одного любого символа, за исключением символа перевода строки (\n). [48]
265

Выражение "13." будет означать 13 + по меньшей мере один любой символ (включая пробел): 1133,
11333, но не 13 (отсутствуют дополнительные символы).
Символ -- ^ -- означает начало строки, но иногда, в зависимости от контекста, означает отрицание в регулярных выражениях.
Знак доллара -- $ -- в конце регулярного выражения соответствует концу строки. Выражение "^$" соответствует пустой строке.
Символы ^ и $ иногда еще называют якорями, поскольку они означают, или закрепляют, позицию в регулярных выражениях.
Квадратные скобки -- [...] -- предназначены для задания подмножества символов. Квадратные скобки, внутри регулярного выражения, считаются одним символом, который может принимать значения, перечисленные внутри этих скобок..
Выражение "[xyz]" -- соответствует одному из символов x, y или z.
Выражение "[c-n]" соответствует одному из символов в диапазоне от c до n, включительно.
Выражение "[B-Pk-y]" соответствует одному из символов в диапазоне от B до P или в диапазоне от k до y, включительно.
Выражение "[a-z0-9]" соответствует одному из символов латиницы в нижнем регистре или цифре.
Выражение "[^b-d]" соответствует любому символу, кроме символов из диапазона от b до d, включительно. В данном случае, метасимвол ^ означает отрицание.
Объединяя квадратные скобки в одну последовательность, можно задать шаблон искомого слова. Так, выражение "[Yy][Ee][Ss]" соответствует словам yes, Yes, YES, yEs и так далее.
Выражение "[0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]" определяет шаблон для поиска любого номера карточки социального страхования (для США).
Обратный слэш -- \ -- служит для экранирования специальных символов, это означает, что экранированные символы должны интерпретироваться буквально, т.е. как простые символы.
Комбинация "\$" указывает на то, что символ "$" трактуется как обычный символ, а не как признак конца строки в регулярных выражениях. Аналогично, комбинация "\\" соответствует простому символу "\".
Экранированные "угловые скобки" -- \<...\> -- отмечают границы слова.
Угловые скобки должны экранироваться, иначе они будут интерпретироваться как простые символы.
Выражение "\<the\>" соответствует слову "the", и не соответствует словам "them", "there", "other" и т.п.
bash$ cat textfile
This is line 1, of which there is only one instance.
This is the only instance of line 2.
This is line 3, another line.
This is line 4.
266

bash$ grep 'the' textfile
This is line 1, of which there is only one instance.
This is the only instance of line 2.
This is line 3, another line.
bash$ grep '\<the\>' textfile
This is the only instance of line 2.
Дополнительные метасимволы. Использующиеся при работе с egrep, awk и Perl
Знак вопроса -- ? -- означает, что предыдущий символ или регулярное выражение встречается 0 или 1 раз. В основном используется для поиска одиночных символов.
Знак "плюс" -- + -- указывает на то, что предыдущий символ или выражение встречается 1 или более раз. Играет ту же роль, что и символ "звездочка" (*), за исключением случая нулевого количества вхождений.
#GNU версии sed и awk допускают использование "+",
#но его необходимо экранировать.
echo a111b | sed -ne '/a1\+b/p' echo a111b | grep 'a1\+b'
echo a111b | gawk '/a1+b/'
# Все три варианта эквивалентны.
# Спасибо S.C.
Экранированные "фигурные скобки" -- \{ \} -- задают число вхождений предыдущего выражения.
Экранирование фигурных скобок -- обязательное условие, иначе они будут интерпретироваться как простые символы. Такой порядок использования, технически, не является частью основного набора правил построения регулярных выражений.
Выражение "[0-9]\{5\}" -- в точности соответствует подстроке из пяти десятичных цифр (символов из диапазона от 0 до 9, включительно).
В "классической" (не совместимой с POSIX) версии awk, фигурные скобки не могут быть использованы. Однако, в gawk предусмотрен ключ --re-interval, который позволяет использовать (неэкранированные) фигурные скобки.
bash$ echo 2222 | gawk --re-interval '/2{3}/'
2222
Язык программирования Perl и некоторые версии egrep не требуют экранирования фигурных скобок.
Круглые скобки -- ( ) -- предназначены для выделения групп регулярных выражений. Они полезны при использовании с оператором "|" и при извлечении подстроки с помощью команды expr.
267

Вертикальная черта -- | -- выполняет роль логического оператора "ИЛИ" в регулярных выражениях и служит для задания набора альтернатив.
bash$ egrep 're(a|e)d' misc.txt
People who read seem to be better informed than those who do not. The clarinet produces sound by the vibration of its reed.
Некоторые версии sed, ed и ex поддерживают экранированные версии регулярных выражений, описанные выше.
Классы символов POSIX. [:class:]
Это альтернативный способ указания диапазона символов.
Класс [:alnum:] -- соответствует алфавитным символам и цифрам. Эквивалентно выражению A-
Za-z0-9.
Класс [:alpha:] -- соответствует символам алфавита. Эквивалентно выражению A-Za-z.
Класс [:blank:] -- соответствует символу пробела или символу табуляции.
Класс [:cntrl:] -- соответствует управляющим символам (control characters).
Класс [:digit:] -- соответствует набору десятичных цифр. Эквивалентно выражению 0-9.
Класс [:graph:] (печатаемые и псевдографические символы) -- соответствует набору символов из диапазона ASCII 33 - 126. Это то же самое, что и класс [:print:], за исключением символа пробела.
Класс [:lower:] -- соответствует набору алфавитных символов в нижнем регистре. Эквивалентно выражению a-z.
Класс [:print:] (печатаемые символы) -- соответствует набору символов из диапазона ASCII 32 - 126. По своему составу этот класс идентичен классу [:graph:], описанному выше, за исключением того, что в этом классе дополнительно присутствует символ пробела.
Класс [:space:] -- соответствует пробельным символам (пробел и горизонтальная табуляция).
Класс [:upper:] -- соответствует набору символов алфавита в верхнем регистре. Эквивалентно выражению A-Z.
Класс [:xdigit:] -- соответствует набору шестнадцатиричных цифр. Эквивалентно выражению
0-9A-Fa-f.
Вообще, символьные классы POSIX требуют заключения в кавычки или двойные квадратные скобки ([[ ]]).
bash$ grep [[:digit:]] test.file abc=723
Эти символьные классы могут использоваться, с некоторыми ограничениями,
268

даже в операциях подстановки имен файлов (globbing).
bash$ ls -l ?[[:digit:]][[:digit:]]? |
||
-rw-rw-r-- |
1 bozo bozo |
0 Aug 21 14:47 a33b |
Примеры использования символьных классов в сценариях вы найдете в Пример
12-17 и Пример 12-18.
Sed, awk и Perl, используемые в сценариях в качестве фильтров, могут принимать регулярные выражения в качестве входных аргументов. См. Пример A-13 и Пример A-19.
В качестве стандартного руководства по этой сложной теме можно порекомендовать "Mastering Regular Expressions", автор Friedl. Книга "Sed & Awk" (авторы Dougherty и Robbins) так же дает полное
иясное описание регулярных выражений (см. раздел Библиография).
18.2.Globbing -- Подстановка имен файлов
Bash, сам по себе, не распознает регулярные выражения. Но в сценариях можно использовать команды и утилиты, такие как sed и awk, которые прекрасно справляются с обработкой регулярных выражений.
Фактически, Bash может выполнять подстановку имен файлов, этот процесс называется "globbing", но при этом не используется стандартный набор регулярных выражений. Вместо этого, при выполнении подстановки имен файлов, производится распознавание и интерпретация шаблонных символов. В число интерпретируемых шаблонов входят символы * и ?, списки символов в квадратных скобках и некоторые специальные символы (например ^, используемый для выполнения операции отрицания). Применение шаблонных символов имеет ряд важных ограничений. Например, если имена файлов начинаются с точки (например так: .bashrc), то они не будут соответствовать шаблону, содержащему символ *. [49] Аналогично, символ ? в операции подстановки имен файлов имеет иной смысл, нежели в регулярных выражениях.
bash$ ls -l |
|
|
|
|
|
|
|
|
|
|
|
total 2 |
|
1 |
bozo |
bozo |
|
0 |
Aug |
|
6 |
18:42 |
a.1 |
-rw-rw-r-- |
|
|
|
||||||||
-rw-rw-r-- |
|
1 |
bozo |
bozo |
|
0 |
Aug |
|
6 |
18:42 |
b.1 |
-rw-rw-r-- |
|
1 |
bozo |
bozo |
|
0 |
Aug |
|
6 |
18:42 |
c.1 |
-rw-rw-r-- |
|
1 |
bozo |
bozo |
466 |
Aug |
|
6 |
17:48 |
t2.sh |
|
-rw-rw-r-- |
|
1 |
bozo |
bozo |
758 |
Jul |
30 |
09:02 |
test1.txt |
||
bash$ ls -l |
t?.sh |
|
bozo |
466 |
|
Aug |
6 |
17:48 |
t2.sh |
||
-rw-rw-r-- |
1 |
bozo |
|
||||||||
bash$ ls -l |
[ab]* |
|
bozo |
0 |
Aug |
6 |
18:42 |
a.1 |
|||
-rw-rw-r-- |
1 |
bozo |
|||||||||
-rw-rw-r-- |
|
1 |
bozo |
bozo |
|
0 |
Aug |
|
6 |
18:42 |
b.1 |
bash$ ls -l |
[a-c]* |
bozo |
0 |
Aug |
6 |
18:42 |
a.1 |
||||
-rw-rw-r-- |
1 |
bozo |
|||||||||
-rw-rw-r-- |
|
1 |
bozo |
bozo |
|
0 |
Aug |
|
6 |
18:42 |
b.1 |
-rw-rw-r-- |
|
1 |
bozo |
bozo |
|
0 |
Aug |
|
6 |
18:42 |
c.1 |
bash$ ls -l |
[^ab]* |
bozo |
0 |
Aug |
6 |
18:42 |
c.1 |
||||
-rw-rw-r-- |
1 |
bozo |
|||||||||
-rw-rw-r-- |
|
1 |
bozo |
bozo |
466 |
Aug |
|
6 |
17:48 |
t2.sh |
|
-rw-rw-r-- |
|
1 |
bozo |
bozo |
758 |
Jul |
30 |
09:02 |
test1.txt |
||
bash$ ls -l |
{b*,c*,*est*} |
0 |
Aug |
6 |
18:42 |
b.1 |
|||||
-rw-rw-r-- |
1 |
bozo |
bozo |
||||||||
-rw-rw-r-- |
|
1 |
bozo |
bozo |
|
0 |
Aug |
|
6 |
18:42 |
c.1 |
-rw-rw-r-- |
|
1 |
bozo |
bozo |
758 |
Jul |
30 |
09:02 |
test1.txt |
269