Подстановка ${foo:?bar}
выведет на экран foo: bar
и аварийно завершит команду, если переменной foo
не существует или ее значение не определено. И наконец, ${foo:+bar}
вернет bar
, если foo
существует и не равна null
. Какое разнообразие вариантов!
Шаблон {foo#*/}
задает поиск и удаление только левого символа /
(символ *
соответствует любой строке, в том числе и пустой). Шаблон {foo##*/}
задает поиск максимальной подстроки, совпадающей с ним, и, таким образом, удаляет самый правый символ / и все предшествующие ему символы.
Шаблон ${bar%local*}
определяет просмотр символов в значении параметра, начиная от крайнего правого, до первого появления подстроки local
, за которой следует любое количество символов, а в случае шаблона ${bar%%local*}
ищется максимально возможное количество символов, начиная от крайнего правого символа значения и заканчивая крайним левым появлением подстроки local
.
Поскольку в системах UNIX и Linux многое основано на идеи фильтров, результат какой-либо операции часто должен перенаправляться вручную. Допустим, вы хотите преобразовать файлы GIF в файлы JPEG с помощью программы cjpeg:
$ cjpeg image.gif > image.jpg
Порой вам может потребоваться выполнить такого рода операцию над большим числом файлов. Как автоматизировать подобное перенаправление? Это очень просто:
#!/bin/sh
for image in *.gif
do
cjpeg $image > {image%%gif}jpg
done
Этот сценарий, giftojpeg, создает в текущем каталоге для каждого файла формата GIF файл формата JPEG.
Особый способ передачи из сценария командной оболочки входных данных команде — использование встроенного документа (here document). Такой документ позволяет команде выполняться так, как будто она читает данные из файла или с клавиатуры, в то время как на самом деле она получает их из сценария.
Встроенный документ начинается со служебных символов <<
, за которыми следует специальная символьная последовательность, повторяющаяся и в конце документа. Символы <<
обозначают в командной оболочке перенаправление данных, которое в данном случае заставляет вход команды превратиться во встроенный документ. Специальная последовательность символов действует как маркер, указывая оболочке, где завершается встроенный документ. Маркерная последовательность не должна включаться в строки, передаваемые команде, поэтому лучше всего сделать ее запоминающейся и четко выделяющейся.
Рассмотрим упражнение 2.19.
Упражнение 2.19. Применение встроенных документов
Простейший пример просто передает входные данные команде cat
.
#!/bin/sh
cat <
hello
this is a here
document
!FUNKY!
Этот пример выводит на экран следующие строки:
hello
this is a here
document
Встроенные документы могут показаться странным средством, но они очень полезны, т.к. позволяют запускать интерактивные программы, например редактор, и снабжать их каким-либо заранее определенным вводом. Но особенно часто они применяются при выводе из сценария больших порций текста, как вы уже видели, и при этом позволяют избавиться от необходимости применять команду echo
для каждой выводимой строки. Вы можете использовать восклицательные знаки ( !
) с двух сторон от идентификатора документа во избежание путаницы.
Если вы хотите обработать несколько строк заранее определенным способом, можно применить в сценарии строчный редактор ed и передать ему команды из встроенного документа (упражнение 2.20).
Упражнение 2.20. Ещё одно применение встроенного документа
1. Начнем с файла, названного a_text_file и содержащего следующие строки:
That is line 1
That is line 2
That is line 3That is line 4
2. Вы можете отредактировать этот файл, совместно используя встроенный документ и редактор ed:
#!/bin/sh
ed a_text_file <
3
d
., \$s/is/was/ w
q
!FunkyStuff!
exit 0
Если вы выполните этот сценарий, то увидите, что теперь файл содержит следующие строки:
That is line 1
That is line 2
That was line 4
Как это работает
Сценарий командной оболочки запускает редактор ed и передает ему команды, необходимые для перехода к третьей строке, удаления строки и затем замены ее содержимым текущей строки (поскольку строка 3 (line 3) была удалена, теперь текущая строка — последняя строка файла). Эти команды редактора ed берутся из строк сценария, формирующих встроенный документ, строк между маркерами !Funky Stuff!
.
Читать дальше