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

ЖАНРЫ

Основы программирования в Linux
Шрифт:

 my_secret_process $i_tmp

done

Но в каждом проходе цикла вы получите следующее сообщение:

my_secret_process: too few arguments

В чем ошибка?

Проблема заключается в том, что командная оболочка попыталась подставить значение переменной

$i_tmp
, которая не существует. Оболочка не считает это ошибкой; она просто не делает никакой подстановки, поэтому в сценарий my_secret_process не передаются никакие параметры. Для обеспечения подстановки в переменную части ее значения
$i
необходимо
i
заключить в фигурные скобки следующим образом:

#!/bin/sh

for i in 1 2 do

 my_secret_process ${i}_tmp

done

В

каждом проходе цикла вместо
${i}
подставляется значение
i
и получаются реальные имена файлов. Вы подставляете значение параметра в строку.

В командной оболочке можно выполнять разнообразные виды подстановок. Часто они помогают найти красивое решение задач, требующих обработки многих параметров. Самые распространенные виды подстановок значений параметров приведены в табл. 2.18.

Таблица 2.18

Шаблон подстановки параметра Описание
${парам:-значение по умолчанию}
Если у
парам
нет значения, ему присваивается значение по умолчанию
${#парам}
Задается длина
парам
${парам%строка}
От конца значения
парам
отбрасывается наименьшая порция, совпадающая со
строкой
, и возвращается остальная часть значения
${парам%%строка}
От конца значения
парам
отбрасывается наибольшая порция, совпадающая со
строкой
, и возвращается остальная часть значения
${парам#строка}
От начала значения
парам
отбрасывается наименьшая порция, совпадающая со
строкой
, и возвращается остальная часть значения
${парам##строка}
От начала значения
парам
отбрасывается наибольшая порция, совпадающая со
строкой
, и возвращается остальная часть значения

Эти подстановки очень полезны при работе со строками. Последние четыре варианта, удаляющие части строк, особенно пригодятся при обработке имен файлов и путей к ним, как показано в упражнении 2.18.

В приведенном далее сценарии показано применение шаблонов при подстановках значений параметров.

#!/bin/sh

unset foo

echo ${foo:-bar}

foo=fud

echo ${foo:-bar}

foo=/usr/bin/X11/startx

echo ${foo#*/}

echo ${foo##*/}

bar=/usr/local/etc/local/networks

echo ${bar%local*}

echo ${bar%%local*}

exit 0

У этого сценария следующий вывод:

bar

fud

usr/bin/X11/startx

startx

/usr/local/etc/usr

Как это работает

Первая подстановка

${foo:-bar}
дает значение
bar
, поскольку у
foo
нет значения в момент выполнения команды. Переменная
foo
остается неизменной, т.е. она остается незаданной.

Примечание

Подстановка

${foo:=bar}
установила бы значение переменной
$foo
. Этот строковый шаблон устанавливает, что переменная
foo
существует и не равна
null
. Если значение переменной не равно
null
, оператор возвращает ее значение, в противном случае вместо этого переменной
foo
присваивается значение
bar
.

Подстановка

${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 <<!FUNKY!

hello

this is a here

document

!FUNKY!

Этот пример выводит на экран следующие строки:

hello

this is a here

document

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

echo
для каждой выводимой строки. Вы можете использовать восклицательные знаки (
!
) с двух сторон от идентификатора документа во избежание путаницы.

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