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

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

Любой сценарий сформирован из ряда конструкций. Конструкцией могут быть операторы, функции, циклы, условные операторы, как и конструкции, которые не делают ничего (пустые конструкции). Кроме того, конструкции могут быть сгруппированы в группу. Группа конструкций - это также отдельная конструкция. 

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

Условные конструкции как часть управляющей конструкции (ветвления if,then, else) позволяют выполнить те или иные действия в зависимости от определенных условий.

Управляющая конструкция, конструкция описывающая условие и действия, выполняемые в зависимости от истинности условия - это инструкции и группы инструкций(неких элементарных действий), применение которых позволяет изменять по мере необходимости последовательность выполнения других инструкций программы, управляющие конструкции разделяются на ветвления (условные конструкции), циклы и конструкции переходов (java)

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

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



#!/bin/sh

mkdir /home/dave/mydocs    #создание каталога 

ср *.docs /home/dave/docs  #копирование файлов с расширением doc 

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

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

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

Оператор или инструкция — наименьшая автономная часть языка программирования; команда или набор команд. Программа представляет собой последовательность инструкций. По "историческим причинам" русский термин «оператор» обозначает то же, что и «инструкция», которой соответствует английское "statement"

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

Оператор (инструкция) if принято называть условным оператором, поскольку оператор if это часть управляющей конструкции и употребляется в связке с другими операторами (инструкциями): then, elif, else  и ключевым словом fi - логическим end, как знаком конца управляющей конструкции, подразумеваемую конструкцию часто называют оператором if/then, if/else в зависимости от количества блоков конструкции и логической задачей (в Python это будут одноместные, трех местные и тд),  что очевидно точнее по смыслу. 

Оператор if/then проверяет - является ли код завершения списка команд равен Ø (поскольку Ø означает "истина"),  и если это так, то выполняет одну, или более, команд, следующие за словом then.

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

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

https://ru.wikipedia.org/wiki

Цикл — разновидность управляющей конструкции в языках программирования, предназначенная для организации многократного исполнения набора инструкций. Также циклом может называться любая многократно исполняемая последовательность инструкций, организованная любым способом (например, с помощью условного перехода). Цикл, или итерация, — это процесс повторного выполнения наборов команд. В распоряжении пользователя имеется три вида операторов цикла:

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

Оператор if в отличии от оператора for множит операции чтения-записи, поэтому применение if, должно быть обоснованым

Операторы:  if/then  else

Управляющие конструкции в Lua ст.55 (4.3)

Конструкции проверки условий

Оператор if/then позволяет осуществить проверку условий, если точно "механизм условного исполнения вычислителя". Проверка выполняется на основе значений ¨истина¨(Ø) или ¨ложь¨(1), после чего могут вызываться наборы условных операторов:

Условный оператор с одной ветвью

if условие then команды fi

Условный оператор с двумя ветвями

if условие then команды1 else команды2 fi

Условный оператор с несколькими условиями

if   условие1 then команды1

elif условие2 then команды2

elif условие3 then команды3

...

else командыN fi


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

[[]]  - Двойные квадратные скобки:

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

 

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

Синтаксис конструкции if: 

Сначала записывается часть if с условным выражением, далее могут следовать одна или более необязательных частей elif, и, наконец, необязательная часть else. elif  это краткая форма записи конструкции else if. Применяется для построения многоярусных конструкций if/then

 

Общая форма записи условной инструкции if выглядит следующим образом:

if [условие 1]       если [условие 1] истинно 

then                 тогда

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

иначе elif [условие 2]      если [условие 2] истинно

then                        тогда

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

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

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

fi                            конец

Оператор if обязательно завершается ключевым словом fi как ключевым словом окончания управляющей конструкции . Распространенной ошибкой является пропуск слова fi при закрытии оператора if.

Ключевые слова elif и else использовать необязательно.

else - (иначе, другое...) после else может снова быть условный оператор

elif - это краткая форма записи конструкции else if, применяется для построения многоярусных инструкций if/then.

Если оператор не содержит ключевое слово elif, то можно не указывать и else

Оператор if может также включать несколько блоков, начинающихся ключевым словом elif, else. 

Основной конструкцией оператора if является конструкция: if  then  fi.

Нельзя оставлять не заполненными части оператора if, внутри должен находиться какой-либо оператор, для этого есть  пустая команда: true - двоеточие(:) которая всегда возвращает значение 0 в качестве кода возврата, команды можно размещать только в части then, например: if command; then :; else ...; fi

Простые операторы if/then

Конструкцию принято называть "условный оператор с одной ветвью". При выполнении такого оператора вычисляется условие, и если оно истинно, то выполняются команды до ключевого слова fi (общее название в языках програмирования - end), в противном случае выполнение программы продолжается со следующей за условным оператором команды.

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

if: if КОМАНДЫ; then КОМАНДЫ; [ elif КОМАНДЫ; then КОМАНДЫ; ]... [ else КОМАНДЫ; ] fi

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

if условие; then 

команды 

fi

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

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

$ cat > iftest

#!/bin/sh

# iftest

if [ "10" -lt "12" ]

then

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

echo "Yes, 10 is less then 12"

fi

^C

$ chmod +x iftest

$ ./iftest

Yes, 10 is less then 12

Изменим скрипт:

$ vim iftest

#!/bin/sh

# iftest

if [ "20" -gt "12" ]

then

echo "Да 20 больше 12"

fi

$ ./iftest

Да 20 больше 12

Простые операторы if/then else

Конструкцию принято называть "условный оператор с двумя ветвями".

Здесь при истинности условия выполняются команды1 при ложности — команды2. При необходимости проверить последовательно несколько условий возможно каскадирование условных операторов: Следующая форма оператора if применяется чаще всего:

 if [ условие ] 

then 

команды 1 

else

команды 2

fi

 if [ условие1 ]

then

 #если условие1 справедливо выполнить все команды до else или до fi

else

 #если условие1 не справедливо выполнить все команды до fi

fi 

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

Каскадирование условных операторов

if  условие1

 then команды1

  else if условие2 then команды2

   else if условие3 then команды3

...

    else if условиеN-1 then командыN-1

     else командыN fi;

В этом случае условия будут проверяться последовательно, и как только встретится истинное, будет выполнен соответствующий набор команд и исполнение перейдёт к команде, следующей за условным оператором. Если ни одно из условий не окажется истинным, выполняются командыN из ветви else.

if условие1 

 then команды1 

  elif условие2 then команды2

   elif условие3 then команды3

... 

    elif условиеN-1 then командыN-1

     else командыN fi;

Лестница if-else-if

В сценариях часто используется конструкция, которую называют лестницей if-else-if. Общая форма лестницы имеет вид

if      [ condition1 ]  command 1;

else if [ condition2 ]  command 2;

else if [ condition3 ]  command 3;

. . . 

else default-command

fi

Работает эта конструкция следующим образом. Условные выражения операторов if вычисляются сверху вниз. После выполнения некоторого условия, т.е. когда встретится выражение, принимающее значение ¨истина¨(Ø), выполняется ассоциированная с этим выражением команда, а оставшаяся часть лестницы пропускается. Если все условия ложны, то выполняется оператор в последней фразе else, а если последняя фраза else отсутствует, то в этом случае не выполняется ни одна команда. Ключевое слово fi обозначит завершение всего сценария, без необходимости писать его каждый раз после if, поскольку после каждого else if [ condition ]  command  следует разделитель команд (;)

Конструкция if else считается одной цельной командной структурой, если внутри некоторых else нет ничего кроме вложенной конструкции, фигурные скобки таких else можно опустить, в отличии от конструкций с обычными одинарными скобками, выполняющимися в дочернем процессе, вложенные блоки в фигурных скобках, выполняются в рамках того-же процесса, что и сам сценарий.

Вот как описывают каскад else if Брайн Керниган и Роб Пайк  в книге "Практика программирования" ст. 29, говоря о единообразии стиля и устойчивых конструкциях:

Использование каскад else if для реализации многовариантного выбора:

Принятие решений в зависимости от нескольких вариантов выбора описывается такой идиоматической конструкцией (низкоуровневым шаблоном), как цепочка if else if else.

Вот ее общая структура:

if (условие 1)

оператор 1

else if (условие 2)

оператор 2

else if (условие n)

оператор n

else

оператор по умолчанию

Условия проверяются сверху вниз. Как только найдено первое выполняющееся условие, управление передается следующим за ним операторам, а затем остальная часть каскада пропускается. Операторы могут быть одиночными или объединенны­ми в блоки,  группы заключенные  в фигурные скобки. Последний оператор обрабатывает ситуацию "по умолчанию", т.е. случай, когда не выполняется ни одно из условий. Завершающий блок else можно опустить, если по умолчанию ничего не нужно делать. Правда, его можно и оставить, включив туда вывод сообщения об ошибке. Это превентивная мера на случай возникновения "невозможной" ситуации, т.е. непредвиденной в программе. В такой конструкции следует выровнять все ключевые слова else по одной вер­тикальной линии, а не ставить их в соответствие операторам if. Вертикальное выравнивание подчеркивает, что выполняется последовательная проверка, и не дает строкам сползать к правому краю страницы. Длинный каскад вложенных операторов if часто свидетельствует о низком каче­стве кода, а то и об откровенных ошибках в нем:

? if (argc == 3)

?       if ( (fin = fopen(argv[l], "r"))  != NULL)

?             if ( (fout = fopen(argv[2], "w"))  != NULL) {

?                  while ( (c = gete(fin)) != EOF)

?                          putc (c, fout);

?                  felose(fin); felose(fout);

?              } else

?                   printf("Can't open output file %s\n",  argv[2]);

?      else

?            printf("Can't open input file %s\n",  argv[1]);

?      else

?            printf("Usage: ер inputfile outputfile\n");

Этот каскад операторов if требует держать в уме "стек" условий и проверок, чтобы в нужных местах доставать из этого стека информацию о выполняемых опе­рациях (если мы еще будем в состоянии их вспомнить). Поскольку в каждом случае выполняется максимум одна операция, следует воспользоваться системой операто­ров else if. Если изменить порядок проверок и принятия решений, код станет более понятным. Кроме того, удастся устранить некоторую "утечку ресурсов", имев­шую место в исходном варианте:

if (arge != 3)

      printf("Usage: ер inputfile outputfile\n");

else if ( (fin = fopen (argv [1], "r")) == NULL)

      printf("Can't open input file %s\n", argv[l]);

else if ( (fout = fopen(argv[2], "w")) == NULL) {

      printf("Can't open output file %s\n", argv[2]);

      fclose(fin);}

else {

      while ((с = getc(fin)) != EOF)

            putc (с, fout);

      fclose(fin);

      fclose(fout);

}

Проверки выполняются одна за другой, пока одна из них не даст положительный результат. Затем выполняются соответствующие операторы, и управление перехо­дит за пределы последнего else. Общее правило состоит в том, чтобы немедленно сопровождать каждое принятое решение соответствующими операциями, если это возможно. Говоря более простыми словами, как только вы сделали выбор - выполните какую-нибудь операцию."

Команда может быть не одна а несколько в том смысле, что:

if [ condition-true ]

then

   command 1

   command 2

   ...

else

#Необязательная ветка (можно опустить,если в ней нет необходимости),

#дополнительный блок кода, исполняемый в случае, когда результат проверки -- "ложь".

   command 3

   command 4

   ...

fi


if [ condition1 ] 

then 

   command1 

   command2 

   command3 

elif [ condition2 ] 

# То же самое, что и else if 

then 

   command4 

   command5 

else 

  default-command 

fi

Можно заметить, что после if и elif (else if) следует then, а после else if [ condition ] command; (в случае лестницы) следует разделитель команд (;)

Вложенные операторы if

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

if [ condition_1 ]; then

if [ condition_2 ]; then

statements_2

else

statements_2

statements_1 

fi

fi

Следущая конструкция может быть выполнена (то что называется "do-something", сделано что-либо, выполнена какая либо команда ), только если оба условия "condition_1" и "condition_2" истинны. Конечный результат будет таким же как если бы результаты всех проверок были объединены оператором &&.

if [ condition_1 ]; then

if [ condition_2 ]; then

do-something 

fi

fi

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

Главным преимуществом вложенных структур if считается то, что они позволяют "отложить" проверку внутренних условий. Условие внутреннего оператора if проверяется только в том случае, если значение выражения (последнего из выражений в случае применения else) во внешнем условии оказывается равным TRUE. Таким образом, очевидной целью вкладывания операторов if является проверка одного условия только в том случае, если истинно другое. Сложную логику зачастую невозможно реализовать без вложенных операторов if, но как и вложенные циклы, они затруднительны (по началу) для понимания и отладки и если вы собираетесь применять операторы if более чем на трех уровнях вложения ....., подумайте, нельзя ли пересмотреть логику.

Итого:

Когда оператор if появляется внутри другого оператора if, они считаются вложенными. Такое вложение используется для уменьшения числа необходимых проверок. Этот метод часто обеспечивает большую эффективность, однако одновременно он уменьшает наглядность сценария. Если часть else используется во вложенных if, то каждое else соответствует ближайшему предшествующему if и таким образом, при определении последовательности выполнения фрагментов нет двусмысленности.

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

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

$ cat > iftest2

#!/bin/sh

# iftest2

echo -n "Enter your name:"

read NAME

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

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

echo "You did not enter any information"

fi

^C

$ chmod +x iftest2

$ ./iftest2

Enter your name:NEMO

$ ./iftest2

Enter your name: ....ENTER

You did not enter any information

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

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

Чтобы выяснить, была ли выполнена команда grep, можно применить oператор if. В приведенном ниже примере команда grep используется для уточнения, содержится ли в файле iftest2 слово ¨read¨. Обратите внимание на то, что при поиске соответствия используется шаблон ´read\>´.

$ cat > grepif

#!/bin/sh

# grepif

if grep 'read\>' iftest2 > /dev/null 2>&1

then

echo "Great read is in the file"

else

echo "read is not in the file"

fi

^C

$ chmod +x grepif

$ ./grepif

Great read is in the file

В примере вывод команды grep направляется в системную корзину. Если поиск значения, совпадающего с шаблоном, завершился удачно, команда grep возвращает значение Ø. В этом случае происходит естественная интеграция с оператором if; если команда grep успешно завершилась, часть if принимает значение ¨истина¨, если не удачно else.

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

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

$ cat > grepstr

#!/bin/sh

# grepstr

echo -n "Enter a list of names:" 

read list

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

then

echo "Peter is here"

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

else

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

fi

^C

$ chmod +x grepstr

$ ./grepstr

Enter a list of names:Peter

Peter is here

Применение команды exit

https://www.opennet.ru/docs/ 

Часто требуется завершить сценарий на каком то этапе его исполнения, для этого служит команда exit. В инструкции exit есть один необязательный аргумент. Этот аргумент является целым числом, представляющим код возврата, которые возвращается в родительский процесс и запоминается в переменной $?, и в последствии можно проанализировать этот код:  echo $?. Если аргумент нулевой, то это означает, что скрипт проработал успешно, назначив любое другое значение программисты могут использовать для возврата в родительский процесс различных сообщений с тем, чтобы в соответствие с неудачным или успешным завершением дочернего процесса выполнять различные действия (еще одно "условие"). Если в команде exit аргумент не задан, родительская оболочка будет использовать текущее значение переменной $?. Вообщем, кроме завершения "чего либо", команда exit используется для выхода с заданным статусом, то есть команде exit можно явно указать код возврата, в виде: 

exit nnn, где nnn -- это код возврата (число в диапазоне 0 - 255). И все это актуально при отладке и поиске ошибок (устоявшееся название - "возвращаемое значение"):

$ cat > exxit

#!/bin/sh

echo "$? ---> предыдущий код возврата"

exit 254

^C

$ chmod +x exxit

$ ./exxit

0 ---> предыдущий код возврата

$ echo $?

254

254 ---> возвращаемое значение скрипта. В итоге можно "нагородить" ..что угодно:

$ cat > exxit1

#!/bin/sh

./exxit

if [ "$?" -eq "254" ]

then

echo "happy"

exit 255

fi

$ chmod +x exxit1

$ ./exxit1

0 ---> предыдущий код возврата

happy

$ echo $?

255

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

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

$ cat > ifpwd

#!/bin/sh

#ifpwd

echo "Script name:$0"

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

echo "You need to be in the root dir,from: "$PWD" not to run this script" >&2

exit 1

fi

^C

$ chmod +x ifpwd

$ ./ifpwd

Script name:./ifpwd

You need to be in the root dir,from: /home/user not to run this script

$

Если (if) условие: [ "$PWD" != "/" ] ($PWD не равно "/" ) истина (что есть истина),

Тогда (then): "You need to be in the root dir,from: "$PWD" not to run this script" >&2

Сменим директорию, скопируем скрипт и выполним его из "/":

$ cd /

su

Password: 

# cp /home/user/ifpwd /

# ./ifpwd

Script name:./ifpwd

Если (if) условие: [ "$PWD" != "/" ] ($PWD не равно "/" ) истина (что есть ложно),

Тогда (then): exit 1

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

http://www.ibm.com/developerworks/bash-parameters/

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

$ cat > ifparam

#!/bin/sh

# ifparam

if [ "$#" -lt 3 ]; then

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

# Usage: 'script $0'arg1 arg2 arg3,

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

echo "Usage: 'script $0'arg1 arg2 arg3" >&2

exit 1

fi

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

echo "arg1: $1"

echo "arg2: $2"

echo "arg3: $3"

^C

$ chmod +x ifparam

$ ./ifparam ZZZ

Usage: 'script ./ifparam'arg1 arg2 arg3

$ ./ifparam ZZZ XXX CCC

arg1: ZZZ

arg2: XXX

arg3: CCC

Если (if) условие: [ "$#" -lt 3 ]  ( if [ "$a" -lt "$b" ] Первое число меньше второго числа) истина, Тогда (then): echo "Usage: 'script $0'arg1 arg2 arg3" >&2 ; exit 1

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

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

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

$ cat > 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

^C

$ chmod +x ifcp

$ ./ifcp

cp: cannot stat 'myfile': No such file or directory

ifcp: error could not copy the files

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

$ cat > ifcp1

#!/bin/sh

#ifcp1

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

^C

$ chmod +x ifcp1

$ ./ifcp1

ifcp1: error could not copy the files 

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

$ cat > myfile

test

test

test

^C

$ ./ifcp1

good copy

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

Можно также осуществлять контроль прав доступа к файлу. Ниже приводится несложная проверка на предмет того, можно ли вести записи в файле myfile.log, который переприсвоен переменной LOGFILE:

$ cat > ifwright

#!/bin/sh

# ifwright

LOGFILE=myfile.log

echo "$LOGFILE"

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

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

fi

^C

$ chmod +x ifwright

$ ./ifwright

myfile.log

 You cannot write to myfile.log  

$ ls -l myfile.log

-r-------- 1 user user  15 Oct  9 18:23 myfile.log

$

Если (if) условие: [ ! -w "$LOGFILE" ]  (! - возврвщает истину если условие ложно ) истина (что есть истина), Тогда (then): " You cannot write to $LOGFILE " >&2 

Сменим права на файл myfile.log:

$ chmod 755 myfile.log

$ ./ifwright

myfile.log

$ ls -l myfile.log

-rwxr-xr-x 1 user user 15 Oct 9 18:25 myfile.log

$

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

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

$ cat > 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

^C

$ chmod +x ifinteractive

$ ./ifinteractive

We are interactive with a terminal

Если (if) условие: [ -t ]  ( истина, если FD-файловый дескриптор, открыт на терминале) истина, (что есть истина) Тогда (then): echo "We are interactive with a terminal"  Остальное (else): echo "We must be running from some background process probably cron or at " 

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

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

$ cat > ifeditor

#!/bin/sh

# ifeditor

if [ -z "$EDITOR" ]; then

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

echo "Your editor environment is not set" 

else

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

echo "Using $EDITOR as the default editor" 

fi

^C

$ chmod +x ifeditor

$ [ -z "$EDITOR" ]  # эта строка нулевая

$ echo $?

0     # Да

$ echo $EDITOR


$ ./ifeditor

Your editor environment is not set

Если условие: [ -z "$EDITOR" ] (Эта строка нулевая ) истина

Тогда (then): echo "Your editor environment is not set"

Остальное (else): echo "Using $EDITOR as the default editor"

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

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

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

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

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

$ cat > ifroot

#!/bin/sh

# ifroot

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

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

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

exit 1

else

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

echo "Yes indeed you are $LOGNAME proceed"

fi

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

echo "test test test"

^C

$ chmod +x ifroot

$ ./ifroot

You need to be root to run this script

$ sudo ./ifroot

Yes indeed you are root proceed

test test test

Если (if) условие: [ "$LOGNAME" != "root" ] (Две строки не равны ) истина, 

Тогда (then): echo "You need to be root to run this script" >&2

Остальное (else): "Yes indeed you are $LOGNAME proceed"

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

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

if [ "$DIRECTORY" = "" ] ( if [ "$a" = "$b" ] Две строки равны)

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

if [ $# -lt 1] ($# количество аргументов командной строки) ( if [ "$a" -lt "$b" ] Первое число меньше второго числа)

Если строка нулевая, отображается "укажите директорию для создания" и сценарий завершается.

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

Если пользователь ввел параметр, он получает запрос: действительно ли нужно создавать каталог?.

Если он вводит символ "y", сравнивается значение переменной $ANS, после нажатия пользователем клавиши [Enter] ( read-проверка значений) , и если истина, отображается "Creating OK!" создается каталог полученный сценарием в параметре и присвоенный переменной $DIRECTORY.

Если он вводит символ, отличный от "у", сравнивается код завершения последней команды 

(else [ $? != 0 ]), и если истина, отображается "Errors creating the directory $DIRECTORY" .

$ cat > ifmkdir

#!/bin/sh

#ifmkdir

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

DIRECTORY=$1

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

if [ "$DIRECTORY" = "" ]

then

# если да "укажите директорию для создания"

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

exit 1

fi

# если истина, что "FILE" существует и каталог

if [ -d "$DIRECTORY" ]

then

echo "The directory does exist!" #директория существует

exit 1

fi

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

read ANS

if [ "$ANS" = "y" ]; then

echo "Creating OK!"

# создает каталог и все данные вывода в /dev/null

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

else [ $? != 0 ] 

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

exit 1

fi

^C

$ chmod +x ifmkdir

$ ./ifmkdir

Usage: ifmkdir specify the directory to create!

$ ./ifmkdir dir1

Create it now? [y/n]:y

Creating OK!

$ ./ifmkdir dir3

Create it now? [y/n]:y

Creating OK!

$ mkdir dir2

$ ./ifmkdir dir2

The directory does exist!

$ ./ifmkdir dir4

Create it now? [y/n]: ....ENTER

Errors creating the directory dir4

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

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

$ cat > ifdirect

#!/bin/sh

# ifdirec

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

DIRECTORY=$1

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

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

echo "$DIRECTORY: is indeed empty"

else

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

echo "$DIRECTORY: is not empty"

fi

^C

$ chmod +x ifdirect

Создадим пару каталогов: emptydir и notemptydir , и скопируем в один из них наш скрипт

$ mkdir emptydir notemptydir

$ cp ifdirect /home/user/notemptydir

$ ./ifdirect emptydir

emptydir: is indeed empty

$ ./ifdirect notemptydir

notemptydir: is not empty

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

Обычно при проведении проверки условий выполняются части then и else. Иногда независимо от того, истинно или ложно условие, нет необходимости переходить к действиям. К сожалению, нельзя оставлять незаполненными части оператора if — здесь должен находиться какой-либо оператор. Чтобы разрешить это затруднение, интерпретатор shell поддерживает команду null (пустая операция -двоеточие `:`) . Команда null всегда возвращает значение “истина”, что в данном случае нас удовлетворяет. Возвращаясь к предыдущему примеру, заметим, что если каталог пуст, команды можно размещать только в части then.

$ cat > ifdirectory

#!/bin/sh

# ifdirecory

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

DIRECTORY=$1

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

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

echo "$DIRECTORY: is indeed empty"

else :

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

fi

^C

$ chmod +x  ifdirectory

$ ./ifdirectory emptydir 

emptydir: is indeed empty

$ ./ifdirectory notemptydir 

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

cp — команда Unix в составе GNU, предназначенная для копирования файлов. Чтобы скопировать файл:

cp [ -f ] [ -h ] [ -i ] [ -p ][ -- ]  исходный_файл   целевой_файл

Чтобы скопировать файл или файлы в другой каталог:

cp [-R] [-H | -L | -P] [-f | -i] [-pv]  исходный_файл(или несколько)   целевая_директория

Чтобы скопировать каталог в другой каталог (должен быть использован флаг -r или -R):

cp [ -f ] [ -h ] [ -i ] [ -p ] [ -- ] { -r | -R }  исходная_директория(или несколько)   целевая_директория

     [ -r ]    Рекурсивно - со всеми вложенными папками и(или) файлами

http://www.opennet.ru/man=cp

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

$ cat > 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

^C

$ chmod +x ifcp2

Создадим файл zzz и скопируем его в zzz.bac при помощи сценария:

$ > zzz

$ ./ifcp2 zzz zzz.bac

$ ls -l zzz.bac

-rw-r--r-- 1 user user 0 Oct 10 16:32 zzz.bac

$

Попробуем сделать тоже с не существующим файлом xxx:

$ ./ifcp2 xxx xxx.bac

ifcp2: ERROR failed to copy xxx to xxx.bac

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

$ cat > ifsort

#!/bin/sh

# ifsort

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

# если отсортировано

then : # ничего делать

else 

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

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

fi

^C

$ chmod +x ifsort

Как и в предыдущем примере проверим работу скрипта на существующем файле zzz и не существующем xxx:

$ ./ifsort zzz

$ ./ifsort xxx

ifsort: Oops..errors could not sort !

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

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

cat > ifseted

#!/bin/sh

#ifseted

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

if [ -z "$EDITOR" ]; then

echo "EDITOR environment is not set"

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

else

echo "your eritor type: $EDITOR"

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

fi

read ANS

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

if [ "$ANS" = "y" ]; then

echo -n "type here your editor type and press ENTER:"

else

exit

fi

read EDITOR

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

if [ -z "$EDITOR" ]; then

echo "EDITOR environment is not set"

exit

else

# дописываем в профильный файл присваивание значения

# и export переменной $EDITOR

echo "export EDITOR=$EDITOR" >> ~/.profile

fi

echo "Editor:$EDITOR after reboot will be the default editor,"

echo "or run the command: (. .profile) for the current shell"

^C

$ chmod +x ifseted

Проверим работу сценария:

$ echo $EDITOR 

# значения нет

$ ./ifseted

EDITOR environment is not set

Do you wish to change it now? [y/n]:n # отказался менять

$ # exit

$ ./ifseted

EDITOR environment is not set

Do you wish to change it now? [y/n]: # не ввел названия

$ # exit 

$ ./ifseted

EDITOR environment is not set

Do you wish to change it now? [y/n]:y

type here your editor type and press ENTER:vim

Editor:vim after reboot will be the default editor,

or run the command: (. .profile) for the current shell

$ . .profile

$ echo $EDITOR

vim











Сначала сценарий проверяет установлена ли переменная EDITOR: if [ -z "$EDITOR" ]; then если выполнено условие [строка нулевая] тогда: "EDITOR environment is not set" и предлагается изменить состояние, то есть назначить редактор: 

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

,если редактор назначен условие ложно [строка не нулевая] выводится: название установленного редактора "your eritor type: $EDITOR" и предлагается изменить состояние, то есть назначить другой редактор: 

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

Далее для обоих случаев выполняется команда read и проверяется состояние переменной $ANS: 

if [ "$ANS" = "y" ]; then

если условие не выполнено [строка не равна ¨y¨] тогда: 

exit

если выполнено условие [строка равна ¨y¨] тогда  предлагается ввести название редактора:  

echo -n "type here your editor type and press ENTER:"

Выпоняется команда read и проверяется состояние переменной $EDITOR: 

if [ -z "$EDITOR" ]; then

если выполнено условие [строка нулевая, пользователь ни чего не вводил ] тогда: 

echo "EDITOR environment is not set"; exit

если условие не выполнено [строка не нулевая, пользователь что то ввел] тогда: сценарий дописывает в профильный файл строку, присвая значения и выполняет export переменной $EDITOR: 

echo "export EDITOR=$EDITOR" >> ~/.profile

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

Если нет желания или возможности перезагрузить систему то можно воспользоваться командой: source "." (точка), о чем как и о необходимости перезагрузки сообщается пользователю:

Editor:$EDITOR after reboot will be the default editor, or run the command: (. .profile) for the current shell.

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

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

$ cat > ifmkdir2

#!/bin/sh

#ifmkdir2

DIR_NAME=testdirect

THERE=`pwd` #переменная ТАМ = PWD - текущий каталог

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

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

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

if [ -d $D1R_NAME ]; then

echo "1.dir $DIR_NAME created"

cd $DIR_NAME #сменить каталог

fi

if [ $? = 0 ]; then #если успешно

HERE=`pwd` #переменная ЗДЕСЬ = PWD - новый каталог

#копируем все .txt из ТАМ в ЗДЕСЬ и перенаправление потока вывода в /dev/null

cp $THERE/*.txt $HERE > /dev/null 2>&1

fi

if [ $? = 0 ]; then #если успешно

echo "2.all files .txt copied"

else #если нет

echo "2.Cannot cp to $DIR_NAME" >&2

exit 1

fi

^C

$ chmod +x ifmkdir2

Проверим работу сценария в случае отсутствия файлов с расширением .txt в текущей директории и в случае их наличия:

$ ./ifmkdir2

1.dir testdirect created

2.all files .txt copied

$ cd testdirect

~/testdirect $ ls -l

total 68K

-rwxr-xr-x 1 user user 111 Oct 10 21:36 args.txt*

-rw-r--r-- 1 user user 121 Oct 10 21:36 blacklist.txt

....................................................................

-rw-r--r-- 1 user user 158 Oct 10 21:37 video.txt

~/testdirect $ 

Или так: 

1.dir testdirect created

2.Cannot cp to testdirect

$

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

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

#!/bin/sh

#ifcounter

COUNTER=100

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

read ANS

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

# да, пользователь желает изменить значение

echo "Enter a sensible value "

read VALUE

#простой тест, является ли значение численным (добавим к VALUE любое число),

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

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

STATUS=$?

#проверим код возврата для ехрг и пустую строку для VALUE

  if [ "$STATUS" -ne 0 -o -z "$VALUE" ]; then

    echo "You either entered nothing or a non-numeric " >&2

    echo "Sorry now exiting..counter stays at $COUNTER " >&2

    exit 1

    else

    echo "\$COUNTER =" $COUNTER

    echo "\$VALUE =" $VALUE

    COUNTER=`expr $VALUE + $COUNTER`

    echo "Counter now set to $COUNTER"

    echo "Counter stays at $COUNTER"

  fi

fi

В сценарии используется вложение оператора if, после проверки верхнего и нижнего регистра ¨y¨, по средствам сравнения строк и логического ИЛИ (|| - двойной пайп).

Проверка численного значения переменной STATUS и пустой строки переменной VALUE:

if [ "$STATUS" -ne 0 -o -z "$VALUE" ]; then

где применяется "числовой оператор"  -ne , "логический"    -o ,"оператор строки" -z,

Добавление к постоянному значению COUNTER=100 вводимого значения:

COUNTER=`expr $VALUE + $COUNTER` при помощи expr, после чего результаты выводятся на экран.

$ ifcounter

Do you wish to change the counter value currently set at 100? [y/n]

y

Enter a sensible value 

23

$COUNTER = 100

$VALUE = 23

Counter now set to 123

Counter stays at 123

Простой сценарий, обеспечивающий безопасность при регистрации

stty - установка характеристик терминала (stty --help)

Команда stty устанавливает определенные характеристики терминального ввода/вывода для устройства, являющегося стандартным вводом; команда введенная без аргументов выдает некоторые из уже установленных характеристик. Команда stty работает с файловым дескриптором своего стандартного входного или выходного потока (в зависимости от конкретной системы). Опции команды stty могут следовать в любом порядке и в любых сочетаниях. Дефис перед опцией отменяет ее.

Если терминал ведёт себя странно, последовательность:  

"^J stty sane^J" может его вылечить! (возможно)

"^J" -- символ, соответствующий концу строки.

http://www.opennet.ru/man.shtml?topic=stty

http://uneex.ru/Books/LinuxIntro

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

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

Текущие установки команды stty сохраняются, скрываются символы, которые вводятся в поле пароля (stty -echo).

После команды read установки stty восстанавливаются, и далее по логике сценария:

Если вводится корректный ID пользователя и пароль (паролем является pass), переменные INVALID_USER и INVALID_PASSWD для недействительного пользователя или пароля имеют значение ¨nо¨. Затем производится тестирование, и если какая-либо из переменных принимает значение ¨yes¨, сценарий для этого пользователя завершается по умолчанию и наоборот: 

echo "OK correct user ID and password given". К работе допускаются пользователи с действительными ID и паролями. В регистрационном сценарии удобно применять описанное структурное дополнение. В данном примере действительными ID пользователя служат ¨nobody¨ или ¨everybody¨.

$ pg ifpass

#!/bin/sh

# ifpass

# установим значения переменных в "ложь”

INVALID_USER=yes

INVALID_PASSWD=yes

# сохранение текущих установок команды stty в переменную $SAVEDSTTY

SAVEDSTTY=`stty -g`

echo "You are logging into a sensitive area"

echo -n "Enter your ID name: "

read NAME

#(stty -echo) не отображать вводимые символы

stty -echo

echo "Enter your password: "

read PASSWORD

# попробуем снова, вернем stty начальные установки

stty $SAVEDSTTY

  if [ "$NAME" = "nobody" ] || [ "$NAME" = "everybody" ]; then

  # если  ID действительно, установите переменную

  INVALID_USER=no

  fi

    if [ "$PASSWORD" = "pass" ]; then

    # если пароль действителен, установите переменную

    INVALID_PASSWD=no

    fi

      if [ "$INVALID_USER" = "yes" -o "$INVALID_PASSWD" = "yes" ]; then

      echo "`basename $0`: Sorry wrong password or user ID"

      exit 1

      else

      # если вы здесь, ваш ID и пароль в порядке,

      echo "OK correct user ID and password given"

     fi

в итоге:

$ ./ifpass 

You are logging into a sensitive area

Enter your ID name: nobody

Enter your password: 

OK correct user ID and password given

$

Усложнив сценарий например вложениями if можно добиться появления таких сообщений как:  password incorrect, ID incorrect

Проверка нескольких вариантов размещения файла 

Предположим, что к файлу проверки регистрации требуется применить команду cat, файл находится либо в каталоге /usr/local/apps/audit/logs, либо в каталоге /usr/local/audit/logs. Перед применением к файлу команды cat следует убедиться в том, что его можно просматривать, именно это и будет уточняться при проверке. Если файл нельзя найти или же его нельзя просматривать, на экран выводится сообщение об ошибке. Ниже приводится соответствующий сценарий:

$ pg ifcataudit

#!/bin/sh

# ifcataudit

# размещение файла регистрации

LOCAT_1=/usr/local/apps/audit/logs/audit.log

LOCAT_2=/usr/local/audit/audit.logs

if [ -r $LOCAT_1 ]; then

# если файл находится в этом каталоге и может просматриваться,

# применим к нему команду cat

echo "Using LOCAT_1"

cat $LOCAT_1 > /dev/null 2>&1

elif

# иначе, файл должен находиться а этом каталоге и можно его просматривать

[ -r $LOCAT_2 ]

then

echo "Using LOCAT_2"

cat $LOCAT_2 > /dev/null 2>&1

else

# нет ни в одном каталоге...

echo "`basename $0`: Sorry the audit file is not readable

or cannot be located." >&2

exit 1

Если истина if [ -r $LOCAT_1 ]; then файл ¨LOCAT_1=/usr/local/apps/audit/logs/audit.log¨ существует и читаем

echo "Using LOCAT_1" применяется команда cat.

Иначе (тогда если..) если условие [ -r $LOCAT_2 ] файл ¨LOCAT_2=/usr/local/audit/audit.logs¨ существует и читаем

echo "Using LOCAT_2" применяется команда cat.

Если условия не выполняются

echo "`basename $0`: Sorry the audit file is not readable or cannot be located." >&2

Проверим:

$ ifcataudit 

Using LOCAT_1

$ ifcataudit

ifcataudit: Sorry the audit file is not readable

or cannot be located.

$