KnigaRead.com/

Нейл Мэтью - Основы программирования в Linux

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Нейл Мэтью, "Основы программирования в Linux" бесплатно, без регистрации.
Перейти на страницу:

Для того чтобы сделать средства установления соответствия образцам более мощными, можно применять следующие строки-образцы:

[yY] | [Yy][Ее][Ss])

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

Списки

Иногда может понадобиться сформировать последовательность команд. Например, вы хотите выполнить оператор, только если удовлетворяется несколько условий.

if [ -f this_file ]; then

 if [ -f that_file ]; then

  if [ -f the_other_file ]; then

   echo "All files present, and correct"

  fi

 fi

fi

Или вы хотите, чтобы хотя бы одно условие из последовательности условий было истинным.

if [ -f this_file ]; then

 foo="True"

elif [ -f that_file ]; then

 foo="True"

elif [ -f the_other_file ];

 then foo="True"

else

 foo="False"

fi

if ["$foo" = "True" ]; then

 echo "One of the files exists"

fi

Несмотря на то, что это можно реализовать с помощью нескольких операторов if, как видите, результаты получаются очень громоздкими. В командной оболочке есть пара специальных конструкций для работы со списками команд: И-список (AND list) и ИЛИ-список (OR list). Обе они часто применяются вместе, но мы рассмотрим синтаксическую запись каждой из них отдельно.

И-cписок

Эта конструкция позволяет выполнять последовательность команд, причем каждая последующая выполняется только при успешном завершении предыдущей. Синтаксическая запись такова:

оператор1 && оператор2 && оператор3  && ...

Выполнение операторов начинается с самого левого, если он возвращает значение true (истина), выполняется оператор, расположенный справа от первого оператора. Выполнение продолжается до тех пор, пока очередной оператор не вернет значение false (ложь), после чего никакие операторы списка не выполняются. Операция &&проверяет условие предшествующей команды.

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

Выполните упражнение 2.9.

Упражнение 2.9. И-списки

В следующем сценарии вы обращаетесь к файлу file_one (для проверки его наличия, и если файл не существует, создаете его) и затем удаляете файл file_two. Далее И-список проверяет наличие каждого файла и между делом выводит на экран кое-какой текст.

#!/bin/sh


touch file_one

rm -f file_two


if [ -f file_one ] && echo "hello" [ -f file_two ] && echo " there"

then

 echo "in if"

else

 echo "in else"

fi


exit 0

Попробуйте выполнить сценарий, и вы получите следующий вывод:

hello

in else

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

Команды touch и rm гарантируют, что файлы в текущем каталоге находятся в известном состоянии. Далее И-список выполняет команду [ -f file one ], которая возвращает значение true, потому что вы только что убедились в наличии файла. Поскольку предыдущий оператор завершился успешно, теперь выполняется команда echo. Она тоже завершается успешно (echo всегда возвращает true). Затем выполняется третья проверка [ -f file_two ]. Она возвращает значение false, т.к. файл не существует. Поскольку последняя команда вернула false, заключительная команда echo не выполняется. В результате И-список возвращает значение false, поэтому в операторе if выполняется вариант else.

ИЛИ-список

Эта конструкция позволяет выполнять последовательность команд до тех пор, пока одна из них не вернет значение true, и далее не выполняется ничего более. У нее следующая синтаксическая запись:

оператор1 || оператор2 || оператор3 || ...

Операторы выполняются слева направо. Если очередной оператор возвращает значение false, выполняется следующий за ним оператор. Это продолжается до тех пор, пока очередной оператор не вернет значение true, после этого никакие операторы уже не выполняются.

ИЛИ-список очень похож на И-список, за исключением того, что правило для выполнения следующего оператора — выполнение предыдущего оператора со значением false.

Рассмотрим упражнение 2.10.

Упражнение 2.10. ИЛИ-списки

Скопируйте сценарий из предыдущего упражнения и измените затененные строки следующим образом.

#!/bin/sh


rm -f file_one


if [ -f file_one ] || echo "hello" || echo " there" then

 echo "in if"

else

 echo "in else"

fi


exit 0

В результате выполнения данного сценария будет получен следующий вывод:

hello

in if

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

В первых двух строках просто задаются файлы для остальной части сценария. Первая команда списка [ -f file one ] возвращает значение false, потому что файла в каталоге нет. Далее выполняется команда echo. Вот это да — она возвращает значение true, и больше в ИЛИ-списке не выполняются никакие команды. Оператор if получает из списка значение true, поскольку одна из команд ИЛИ-списка (команда echo) вернула это значение.

Результат, возвращаемый обоими этими списками, — это результат последней выполненной команды списка.

Описанные конструкции списков выполняются так же, как аналогичные конструкции в языке С, когда проверяются множественные условия. Для определения результата выполняется минимальное количество операторов. Операторы, не влияющие на конечный результат, не выполняются. Обычно этот подход называют оптимизацией вычислений (short circuit evaluation).

Комбинирование этих двух конструкций — высшее блаженство для любителей логических задач. Попробуйте проанализировать следующий список:

[ -f file_one ] && команда в случае true || команда в случае false

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

Операторные блоки

Если вы хотите применить несколько операторов в том месте программного кода, где разрешен только один, например в ИЛИ-списке или И-списке, то можете сделать это, заключив операторы в фигурные скобки {} и создав тем самым операторный блок. Например, в приложении, представленном далее в этой главе, вы увидите следующий фрагмент программного кода:

get_confirm && {

 grep -v "$cdcatnum" $tracks_file > $temp_file

 cat $temp_file > $tracks_file

 echo

 add record_tracks

}

Функции

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

Примечание

Как альтернативу можно использовать разбиение большого сценария на много маленьких, каждый из которых выполняет небольшую задачу. У этого подхода есть несколько недостатков: выполнение вложенного в сценарий другого сценария будет гораздо медленнее, чем выполнение функции. Значительно труднее возвращать результаты, и может появиться большое количество маленьких сценариев. Следует рассмотреть наименьшую практически самостоятельную часть вашего сценария и использовать ее как эталон для того, чтобы определить, когда возникает необходимость разбиения большого сценария на коллекцию меньших по размеру сценариев.

Для определения функции в командной оболочке просто введите ее имя и следом за ним пустые круглые скобки, а операторы тела функции заключите в фигурные скобки.

Имя_функции() {

операторы

}

Выполните упражнения 2.11 и 2.12.

Упражнение 2.11. Простая функция

Давайте начнем с действительно простой функции.

#!/bin/sh


foo() {

 echo "Function foo is executing"

}


echo "script starting"

foo

echo "script ended"

exit 0

Выполняющийся сценарий, выведет на экран следующий текст:

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*