355 500 произведений, 25 200 авторов.

Электронная библиотека книг » Дэвид Тейнсли » Linux и UNIX: программирование в shell. Руководство разработчика » Текст книги (страница 13)
Linux и UNIX: программирование в shell. Руководство разработчика
  • Текст добавлен: 15 октября 2016, 00:39

Текст книги "Linux и UNIX: программирование в shell. Руководство разработчика"


Автор книги: Дэвид Тейнсли



сообщить о нарушении

Текущая страница: 13 (всего у книги 25 страниц)

$ expr 30 *.3

90

17.5.1. Приращение переменной цикла

Команда expr выполняет приращение переменной цикла. Сначала переменной цикла присваивается начальное значение нуль. Затем добавляется единица. Кавычки применяются для обозначения подстановки команд. Выводимые данные, полученные с помощью команды expr, присваиваются переменной цикла.

$ loop=0

$ LOOP=`expr $LOOP + 1`

17.5.2. Проверка численных значений

Команду expr можно применять для выполнения сравнений чисел. Если вычисления выполняются с числами, отличными от целых, отображается сообщение об ошибке, например:

$ expr rr + 1

expr: нечисловой аргумент

Итак, необходимо передать значение переменной (не важно, какой именно), выполнить любую арифметическую операцию и направить выводимые данные в /dev/null. Затем достаточно проверить код завершения последней команды. Если код равен нулю, тогда мы имеем дело с числом; любое другое значение свидетельствует о том, что данное значение не является числом.

$ VALUE=12

$ expr $VALUE + 10 > /dev/null 2>&1

$ echo $?

0

Это – число.

$ VALUE=hello

$ expr $VALUE + 10 > /dev/null 2>&1

$ echo $?

2

А это – не численное значение.

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

$ VALUE=hello

$ expr $VALUE="hello"

1

$ echo $?

0

Команда expr возвращает единицу. Не беспокойтесь, все идет хорошо. Теперь выполним проверку с помощью кода завершения последней команды: возвращается значение нуль. В ходе проверки выяснилось, что строка "hello" действительно равна строке "hello".

17.5.3. Поиск по шаблону

С помощью команды expr можно реализовать поиск по шаблону. Подсчет количества символов строки возможен с помощью команды expr. При этом нужно дополнительно указать опцию после двоеточия. Комбинация '. *' означает, что в кавычках может указываться любое количество произвольных символов.

$ VALUE=accounts.doc

$ expr $VALUE : October 8, '.*'

12

Команду expr можно также использовать при поиске совпадающих строк; ниже показано, как применяется шаблон ".doc" для извлечения оставшейся части имени файла.

$ expr $VALUE : '(.*).doc'

accounts

17.6. Заключение

В настоящей главе рассматриваются основные возможности команд test и expr. Показано, как проверяются права доступа к файлу, как тестируются строки. С помощью других условных операторов, типа "if then else" и "case", можно реализовать всестороннюю проверку. Подобный подход позволяет предпринимать определенные действия по результатам проверки.

ГЛАВА 18

Управляющие конструкции

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

   • коды завершения;

   • циклы while, for и until;

   • операторы if then else;

   • принятие решений в сценариях;

   • создание меню.

18.1. Коды завершения

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

$ echo $?

Существует четыре основных типа кодов завершения. Два из них уже упоминались, а именно: код завершения последней команды $? и команды, изменяющие ход выполнения сценария (&&,||). Две оставшиеся разновидности команд имеют отношение к завершению shell–сценария или интерпретатора shell, а также связаны с кодом завершения или кодами возврата функции. Эти коды рассматриваются в главе 19, посвященной изучению функций.

Для завершения текущего процесса в интерпретаторе shell используется команда exit. Общий формат команды:

exit n

где n – числовое значение.

Чтобы завершить работу с интерпретатором shell, не создавая во время текущего сеанса другой интерпретатор shell, достаточно в командной строке ввести команду exit. Если указать команду exit без параметров, интерпретатор shell будет отображать (и отображает) значение последней команды. Существует большое количество

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

Код завершения 0 Успешное завершение, ошибок нет Код завершения 1 Неудачное завершение, имеется ошибка

В shell–сценариях можно реализовать пользовательские коды завершения для выхода из сценария. Желательно, чтобы пользователь чаще применял эту возможность. Какой‑либо иной shell–сценарий или функция, возвращающая результат, могут использовать код завершения вашего сценария. Кроме того, завершение сценария с генерацией кода завершения свидетельствует о культуре программирования. Выполнение сценария обычно завершается после того, как пользователь неправильно вводит данные, если не удается обнаружить ошибку, а также после окончания обычного процесса обработки.

Примечание:

Начиная с этого места книги, все сценарии включают строки комментария. Строки комментария содержат разъяснения, которые помогают запомнить или ясно представить выполнение сценариев. Поскольку интерпретатор команд игнорирует строки комментария, можно располагать их по своему усмотрению. Строка комментария должна начинаться символом #.

18.2. Управляющие конструкции

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

#!/bin/sh

# создание каталога

mkdir /home/dave/mydocs

# копирование всех файлов с расширением doc

cp *.docs /home/dave/docs

# удаление всех файлов с расширением doc

rm *.docs

Рассматриваемый сценарий выполняет определенные задачи. Каковы же могут быть причины возможных неприятностей? Проблема возникнет, например, в том случае, если нельзя будет создать данный каталог. Как поступить в иной ситуации, если каталог может быть создан, но при копировании файлов появляется сообщение об ошибке? Что произойдет, если применить команду cp к разным файлам из различных каталогов. Продуманные решения нужно принимать до применения команды, а еще лучше, если они реализуются при получении результатов выполнения последней команды. Интерпретатор shell приходит здесь на помощь, поддерживая наборы командных операторов, которые помогают принять верное решение в зависимости от успеха или неудачи при выполнении команды либо при обработке списка. Существует два вида таких командных операторов:

   • операторы цикла;

   • операторы, изменяющие ход выполнения сценария.

18.2.1. Операторы, изменяющие ход выполнения сценария

Операторы if, then, else позволяют реализовать условное тестирование. Проверить условия можно самыми различными способами. Например, может производиться оценка размера файла, проверка установленных прав доступа к файлу, сравнение каких‑либо числовых значений или строк. В результате выполнения сравнений возвращается значение "истина" (0) либо "ложь" (1), и затем предпринимаются действия на основании полученного результата. Перед тем как мы приступим к обсуждению условного тестирования, стоит отметить, что некоторые понятия из этой области были рассмотрены ранее.

Операторы case дают возможность выполнять поиск по шаблонам, словам или числовым значениям. После нахождения нужного шаблона или слова можно переходить к выполнению других операторов, которые основываются исключительно на условии, по которому устанавливалось соответствие.

18.2.2. Циклические операторы

Цикл, или итерация, – это процесс повторного выполнения наборов команд. В распоряжении пользователя имеется три вида операторов цикла:


for loop

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

until loop

Используется реже всего. Оператор определяет непрерывное выполнение цикла, пока условие не станет истинным. Проверка условия выполняется в конце цикла

while loop

Задает выполнение цикла до тех пор, пока не будет встречено заданное условие. Проверка условия выполняется в начале цикла

Каждый цикл, содержащий операторы управления ходом выполнения сценария, может быть вложен. Например, внутри цикла for loop может размещаться другой цикл for loop.

После ознакомления с циклами и процессом управления ходом выполнения сценария рассмотрим некоторые сценарии.

С этого момента все операторы echo в сценариях имеют отношение к Linux или UNIX BSD. То есть при выводе на экран используется метод "echo -e -n", при котором не выполняется создание новой строки в конце вывода. В главе 19 будет показано» как можно воспользоваться универсальной командой echo, которая выполняется для обеих разновидностей системы UNIX (System V и BSD).

18.3. Операторы if then else

Оператор if позволяет осуществить проверку условий. Проверка выполняется на основе значений «истина» (0) или «ложь» (1), после чего могут вызываться наборы операторов. Конструкция оператора if идеально подходит для проверки ошибок. Этот оператор имеет следующий формат:

if условие1

then

команды1

elif условие2

then

команды2

else

командыЗ

fi

Рассмотрим подробно, какие действия выполняются при вызове оператора if.


if условие1

если условие1 истинно

than

тогда

команды1

выполняйте команды1

elif условие2

если условие1 ложно

then

тогда

команды2

выполняйте команды2

else

если условие1 или условие2 не выполняется

командыЗ

тогда выполняйте командыЗ

fi

конец

Оператор if обязательно завершается ключевым словом fi. Довольно распространенной ошибкой является пропуск слова f i при закрытии оператора if. Следует отметить, что подобную ошибку могут допускать даже опытные программисты.

Ключевые слова elif и else использовать необязательно. Если оператор не содержит ключевое слово elif, то можно не указывать и else. Оператор if может также включать несколько блоков, начинающихся ключевым словом elif. Основной конструкцией оператора if является конструкция if then fi.

А теперь рассмотрим несколько примеров.

18.3.1. Простые операторы if

Базовая структура оператора if выглядит следующим образом:

if условие

then команды

fi

При использовании оператора if команды ветви then следует указывать в новой строке; если это правило нарушается, отображается сообщение об ошибке. По поводу применения разделителя команд нет единого мнения. Ниже указан разделитель, который будет применяться далее в книге. Простой оператор if в этом случае приобретает вид:

if условие; then

команды fi

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

В следующем примере тестовый оператор используется для проверки того, меньше ли число "10" числа "12". Конечно, это условие истинно, и поэтому выполняются операторы, следующие за частью then; в данном случае, на экран просто выводится соответствующее утверждение. Если условие ложно, сценарий завершается, поскольку этот оператор не содержит части else.

$ pg iftest

#!/bin/sh

#iftest

#это строка комментария, все строки комментария начинаются символом # if [ "10" – lt "12" ]

then

# да, 10 меньше 12

echo "Yes, 10 ls less than 12"

fi

18.3.2. Проверка значений переменных

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

$ pg iftest2

#!/bin/sh

# если test2

echo -n "Enter your name :"

read NAME

# правильно ли пользователь ввел данные ????

if [ "$NAME"="" ] ; then

echo "You did not enter any information" fi

$ iftest2

Enter your name :

You did not enter any information

18.3.3. Проверка вывода команды grep

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

Чтобы выяснить, была ли выполнена команда grep, можно применить оператор if. В приведенном ниже примере команда grep используется для уточнения, содержится ли в файле data.file слово "Dave". Обратите внимание на то, что при поиске соответствия используется шаблон "Dave>".

$ pg grepif

#!/bin/sh

# grepif

if grep 'Dave>' data.file > /dev/null 2>&l

then

echo "Great Dave ls in the file" else

echo "No Dave ls not in the file"

fi

$ grepif

No Dave is not in the file

В примере вывод команды grep направляется в системную корзину. Если поиск значения, совпадающего с шаблоном, завершился удачно, команда grep возвращает

значение 0. В этом случае происходит (естественная интеграция с оператором if; если команда grep успешно завершилась, часть if принимает значение "истина".

18.3.4. Проверка вывода команды grep с помощью переменной

Как уже упоминалось, команду grep можно применять в строке. В следующем сценарии пользователь вводит список имен; затем команда grep ищет переменную, которой присвоено имя некого лица (Peter).

$ pg grepstr

#!/bin/sh

# grepstr

echo -n "Enter a list of names:"

read list

if echo $1ist | grep "Peter" > /dev/null 2>&1

then

echo "Peter ls here"

# можно ли выполнить обработку здесь

else

echo "Peter's not in the list. No comment!"

fi

Ниже приводятся результаты вывода, где содержится несколько имен.

$ grepstr

Enter a list of names:John Louise Peter James

Peter is here

18.3.5. Проверка результата копирования файла

А теперь осуществим проверку того, успешно ли прошло копирование файла. Если команда cp не скопировала файл myfile в файл myfile.bak, отображается сообщение об ошибке. Обратите внимание, что в сообщении об ошибке фигурирует команда `basename $0` которая выводит на экран название сценария.

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

$ pg ifcp

#!/bin/sh

# ifcp

if cp myfile myfile.bak; then

echo "good copy"

else

echo "`basename $0`: error could not copy the files" >&2 fi

$ ifcp

cp: myfile: No such file or directory

ifcp: error could not copy the files

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

отразиться на выводимых данных; сценарий уже отображает сообщения об ошибках, поэтому известно, что он функционирует неверно. Зачем же нам повторное уведомление? Чтобы избавиться от ошибок, генерируемых системой, и системных данных вывода, достаточно применить перенаправление стандартного потока ошибок и потока вывода. Для этого немного перепишем сценарий: > /dev/null 2>&1. В этом случае получим следующее:

$ pg ifcp

#!/bin/sh

# ifcp

if cp myfile myfile.bak >/dev/null 2>&1; then

echo "good copy"

else

echo "`basename $0`: error could not copy the files" >&2

fi

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

$ ifcp

ifcp: error could not copy the files

18.3.6. Проверка текущего каталога

Некоторые сценарии, реализующие административные задачи, можно выполнять из корневого каталога. Если производится глобальное перемещение файлов или же изменяются права доступа к файлу, несложный тест позволяет уточнить, вовлекается ли в этот процесс корневой каталог. В следующем сценарии для хранения текущего каталога переменная DIRECTORY использует подстановку команд. Затем значение этой переменой сравнивается со строкой, содержащей значение "/" (которое и соответствует корневому каталогу). Если значение переменной directory не идентично этой строке, пользователь завершает работу со сценарием. В этом случае код завершения будет 1, что свидетельствует о наличии ошибки.

$ pg ifpwd

#!/bin/sh

# ifpwd DIRECTORY=`pwd`

# захват текущего каталога

if [ "$DIRECTORY" != "/" ]; then

#это корневой каталог ?

#нет, перенаправление вывода в стандартный поток ошибок, который

#отображается на экране по умолчанию.

echo "You need to be in the root directory not $DIRECTORY to run this script" >&2

# выход из сценария со значением 1, ошибка

exit 1

fi

18.3.7. Проверка прав доступа к файлу

Вы можете также осуществлять контроль прав доступа к файлу. Ниже приводится несложная проверка на предмет того, можно ли вести записи в файле test.txt, который переприсвоен переменной logfile.

$ pg ifwr

#!/bin/sh

# ifwr

LOGFILE=test.txt echo $LOGFILE

if [ ! —w "$LOGFILE" ]; then

echo " You cannot write to $LOGFILE " >&2

fi

18.3.8. Проверка параметров, передаваемых сценарию

Оператор if может применяться при определении числа параметров, которые передаются сценарию. Чтобы проверить, соответствует ли количество необходимых параметров количеству вызываемых параметров, используется специальная переменная $#, содержащая число вызываемых параметров.

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

$ pg ifparam

#!/bin/sh

# ifparam

if [ $# -lt 3 ] ; then

#вызывается меньше, чем 3 параметра, на экран выводится сообщение, затем

#прерывается выполнение сценария

echo "Usage: `basename $0` arg1 arg2 arg3" >&2

exit 1

fi

# хорошо, получено 3 параметра, отображаются на экране

echo "arg1: $1"

echo "arg2: $2"

echo "arg3: $3"

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

$ ifparam cup medal

Usage:ifparam argl arg2 arg3

При передаче трех параметров происходит следующее:

$ ifparam cup medal trophy

argl: cup arg2: medal arg3: trophy

18.3.9. Определение интерактивного режима выполнения сценария

Иногда требуется выяснить, выполняется сценарий в интерактивном режиме (режим терминала( либо не в интерактивном режиме (команды cron или at). Такая информация необходима для того, чтобы сценарий мог определить, где можно получить вводимые данные и куда направлять выводимые данные. Чтобы уточнить режим выполнения сценария, достаточно воспользоваться командой test с опцией -t. Если возвращается значение "истина", сценарий выполняется в интерактивном режиме.

$ pg ifinteractive

#! /bin/sh

# ifinteractive

if [ -t ]; then

echo "We are interactive with a terminal"

else

echo "We must be running from some background process probably cron or at " fi

18.3.10. Простые операторы if else

Следующая форма оператора if применяется чаще всего:

if условие

then команды1

else

команды2

fi

Если условие не удовлетворяет тестированию, часть else оператора if позволяет перейти к соответствующей операции.

18.3.11. Проверка установок переменных

Ниже проверяется установка переменной среды editor. Если переменной EDITOR не присвоено значение, пользователь информируется о том, что переменная editor не установлена. Если переменная editor установлена, тип редактора отображается на экране:

$ рg ifeditor

#!/bin/sh

# ifeditor

if [ -z $EDITOR ]; then

#переменная не установлена

echo "Your EDITOR environment is not set"

else

#посмотрим, что же это

echo "Using $EDITOR as the default editor"

18.3.12. Проверка пользователя, выполняющего сценарий

В следующем примере для проверки условия используется переменная среды. Здесь проверяется, присвоено ли переменной LOGNAME значение "root". Обычно этот тип оператора добавляется в начале сценариев в качестве дополнительной меры безопасности. Несомненно, переменная LOGNAME может проверяться для каждого действительного пользователя.

Если значение переменной не равно строке "root", на экран выводится сообщение из стандартного потока ошибок. Пользователь информируется о том, что он не является пользователем root, а сценарий завершается со значением ошибки, равным 1.

Если строка "root" равна значению переменной LOGNAME, выполняется оператор, который находится после else.

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

$ pg ifroot

#!/bin/sh

# ifroot

if [ "$LOGNAME" != "root" ]

# если пользователь не является пользователем root

echo "You need to be root to run this script" >&2

exit 1

else

# да, это пользователь root

echo "Yes indeed you are $LOGNAME proceed"

fi

# выполнение операторов в обычном режиме

18.3.13. Передача параметров сценария системной команде

Позиционные параметры можно передать сценарию, а затем проверить значение переменной. Если при этом пользователь указывает после названия сценария наименование каталога, сценарий заново присваивает специальному параметру $1 более содержательное название, в данном случае directory. С помощью команды ls -A проверяется, не является ли каталог пустым. Если каталог пуст, эта команда не возвращает данные. Затем отображается соответствующее сообщение.

$ pg ifdirec

#!/bin/sh

#ifdirec

#присваивание $1 переменной DIRECTORY DIRECTORY=$1

if [ "`ls -A $DIRECTORY/`"="" ] ; then

# если строка пуста, каталог пуст

echo "$DIRECTORY is indeed empty" else

# в противном случае, нет

echo "$DIRECTORY” is not empty"

fi

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

$ pg ifdirec2

#!/bin/sh

# ifdirec2

DIRECTORY=$1

if [ -z "`ls -A $DIRECTORY`" ] then

echo "$DIRECTORY is indeed empty" else

echo "$DIRECTORY is not empty"

fi

18.3.14. Применение команды null

Обычно при проведении проверки условий выполняются части then и else. Иногда независимо от того, истинно или ложно условие, нет необходимости переходить к действиям.

К сожалению, нельзя оставлять незаполненными части оператора if – здесь должен находиться какой‑либо оператор. Чтобы разрешить это затруднение, интерпретатор shell поддерживает команду null ':'. Команда null всегда возвращает значение "истина", что в данном случае нас удовлетворяет. Возвращаясь к предыдущему примеру, заметим, что если каталог пуст, команды можно размещать только в части then.

$ pg ifdirectory

#!/bin/sh

# ifdirectory

DIRECTORY=$1

if [ "`ls -A $DIRECTORY`"="" ]

then

echo "$DIRECTORY is indeed empty"

else : # не выполняет ничего

fi

18.3.15. Проверка на предмет создания каталога

В продолжение темы каталогов рассмотрим следующий сценарий. Сценарий получает параметр и пытается создать каталог при помощи значения этого параметра. Параметр передается на командную строку и заново присваивается переменной под названием directory. В данном случае проверяется, является ли переменная нулем.

if [ "$DIRECTORY" = "" ]

Вместо предложенного варианта можно воспользоваться общим случаем проверки параметров:

if [ $# -lt 1 ]

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

Пользователь получает запрос, действительно ли нужно создавать каталог. Если он вводит символ, отличный от Y или у, выполняется команда null, в результате чего не предпринимается никаких действий. Каталог создан.

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

$ pg ifmkdir

#!/bin/sh

#ifmkdir

#параметр передается как $1, но заново присваивается переменной DIRECTORY DIRECTORY=$1

#является ли строка пустой ??

if [ "$DIRECTORY"="" ]

then

echo "Usage: `basename $0` directory to create" >&2

exit 1

fi

if [ -d $DIRECTORY ] then :

# ничего не выполняет

else

echo "The directory does exist"

echo -n "Create it now? [y..n] :"

read ANS

if [ "$ANS"="y" ] || [ "$ANS"="Y" ]

then

echo "creating now"

# создайте каталог и перешлите все данные вывода в /dev/null mkdir $DIRECTORY >/dev/null 2>&1 if [ $? != 0 ]; then

echo "Errors creating the directory $DIRECTORY" >&2

exit 1

fi

else :

# ничего не выполняет

fi

При выполнении указанного сценария получим следующее:

$ ifmkdir dt

The directory does exist Create it now? [y..n]: у

creating now

18.3.16. Другие возможности копирования

С помощью команды cp сценарию передается два параметра (они должны содержать имена файлов). Затем системная команда cp копирует значение параметра $1 в параметр $2, а поток вывода перенаправляется в /dev/null. Если команда выполнилась успешно, никаких действий не предпринимается, т. е. применяется команда null.

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

$ pg ifcp2

#!/bin/sh

#ifcp2

if cp $1 $2 > /dev/null 2>&1

# успешно, ничего делать не надо

then :

else

# плохо, покажем пользователю, какие файлы здесь были.

echo "`'basename $0`: ERROR failed to copy $1 to $2"

exit 1

fi

Выполнение сценария при отсутствии ошибки, связанной с командой ср:

$ ifср2 myfile.lex myfile.lex.bak

Сценарий выполняется при наличии ошибок в команде ср:

$ ifcp2 myfile.lexx myfile.lex.bak

ifcp2: ERROR failed to copy myfile.lexx myfile.lex.bak

В следующем примере для сортировки файла под именем accounts.qtr применяется команда sort.

Результаты вывода направляются в системную корзину. Но кому интересно видеть на экране 300 отсортированных строк? Если сортировка прошла успешно, не нужно предпринимать никаких действий; если при выполнении команды имелись сбои, следует сообщить об этом пользователю.

$ pg ifsort

#!/bin/sh

# ifsort

if sort accounts.qtr > /dev/null

# отсортировано. Прекрасно

then :

else

# лучше сообщим об этом пользователю

echo "`basename $0`: Oops..errors could not sort accounts.qtr"

18.3.17. Применение нескольких операторов if

Операторы if можно вкладывать; при этом нужно следить, чтобы каждому ключевому слову if соответствовало слово fi.

18.3.18. Проверка и установка переменных среды

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

$ pg ifseted

#!/bin/sh

#ifseted

#установлена ли переменная EDITOR ?

if [ -z $EDITOR ] ; then

echo "Your EDITOR environment ls not set"

echo "2 will assume you want to use vi..OK"

echo -n "Do you wish to change it now? [y..n] :"

read ANS

# проверка верхнего или нижнего регистра для 'у'

if [ "$ANS"="у" ] || [ "$ANS"="Y" ]; then

echo "enter your editor type :"

read EDITOR

if [ -z $EDITOR ] || [ "$EDITOR"="" ]; then

#если переменная EDITOR не установлена, ей не присвоено значение,

#тогда присвоим ей значение vi

echo "No, editor entered, using vi as default"

EDITOR=vi; export EDITOR

fi

# берется значение и присваивается переменной EDITOR

EDITOR=$EDITOR

export EDITOR

echo "setting $EDITOR"

fi

else

# пользователь

echo "Using vi as the default editor"

EDITOR=vi; export EDITOR

fi

Рассмотрим, как работает приведенный сценарий. Сначала проверим, установлена ли эта переменная. Если это так, появляется сообщение, что редактор vi применяется как редактор, заданный по умолчанию. Затем vi устанавливается в качестве редактора, и сценарий завершается.

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

На данном этапе пользователю предлагается ввести тип редактора. Затем выполняется проверка, не установлен ли данный редактор, а также уточняется, не нажимал ли пользователь во время проверки $editor ="" клавишу [Return]. Действительно эта проверка реализована лучше, чем -z $editor, но оба этих метода приводятся лишь в качестве иллюстрации. Если результаты проверки будут отрицательны, на экран выводится сообщение, что применяется редактор vi, причем значение vi присваивается переменной editor.

Если пользователь вводит имя для переменной editor, происходит присвоение и экспорт этого имени.

18.3.19. Проверка кода завершения последней команды

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

$ pg ifmkd±r2

#!/bin/sh

#ifmkdir2

DIR_NAME=testdirec

#где мы находимся?

THERE=`pwd`

# перенаправление потока вывода в системную корзину

mkdir $DIR_NAME > /dev/null 2>&1

# каталог ли это ?

if [ -d $DIR_NAME ] ; then

# можно ли применить к каталогу команду cd

cd $DIR_NAME

if [ S? = 0 ]; then

# да, можно

HERE=`pwd`

cp $THERE/*.txt $HERE

else

echo "Cannot cd to $DIR_NAME" >&2

exit 1

fi

else

echo "cannot create directory $DIR_NAME" >&2

exit 1

fi

18.3.20. Добавление и проверка целых значений

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

Пользователь может изменить значение путем ввода нового значения, или же ничего не менять, нажав клавишу [Return]. Затем текущее значение выводится на экран, и сценарий завершается.

Если пользователь вводит у или у, поступает приглашение на ввод нового значения, которое добавляется к счетчику. Если пользователь нажимает клавишу [Return], сценарий с помощью команды echo сообщает, что счетчик сохраняет старое значение. Когда пользователь вводит значение, проверка чисел позволяет уточнить, является ли это значение числом. Если это так, значение добавляется к значению counter и затем отображается на экране.

$ pg ifcounter

#!/bin/sh

# ifcounter

COUNTER=100

echo "Do you wish to change the counter value currently set at $COUNTER ? [y...n] :"


    Ваша оценка произведения:

Популярные книги за неделю