Интерпретатор shell

Материал из ПИЭ.Wiki

Перейти к: навигация, поиск

Bourne shell является стандартным интерпретатором команд, который входит в состав всех систем UNIX и совместим с интерпретатором bash в Linux. Существуют и другие интерпретаторы, такие как bash, Korn shell и C shell.

Содержание

Зачем создаются shell-сценарии

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

Структура сценария

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

#!/bin/sh

Система получает указание, где следует искать интерпретатор Bourne shell. Каждый сценарий может содержать комментарии; если комментарии размещаются в сценарии, первым символом в строке комментария будет символ #. Встретив подобный символ, интерпретатор команд игнорирует строку комментария.

Сценарий просматривается интерпретатором команд в направлении сверху вниз. Перед выполнением сценария требуется установить права доступа на выполнение (это можно сделать с помощью команды chmod).

Конструкции языка программирования shell

Язык программирования shell имеет несколько конструкций, которые придадут гибкость вашим программам: комментарии позволят описывать функции программы; "here document" позволяет вам включать в shell программы строки, которые будут перенаправляться как ввод в некоторые команды shell программы; команда exit позволяет завершать программу в нужной точке и использовать коды возврата; конструкции цикла for, while позволяют повторять группу команд в цикле; условные команды if и case выполняют группу команд, если выполнилось некоторое условие; команда break позволяет выполнить безусловный выход из цикла.

Комментарии

Чтобы в программе разместить комментарии, воспользуйтесь знаком #. Если знак # стоит после команды, то сама команда выполняется, а комментарий игнорируется. Формат строки комментария: #comment<CR>

"Here document"

"Here document" позволяет размещать в shell программе строки, которые перенаправляются в качестве ввода команды в этой программе. Это один из способов обеспечения ввода для команды в shell программе без использования отдельного файла. Запись состоит из символа перенаправления << и разделителя, который указывает начало и конец строк ввода. В качестве разделителя может использоваться один символ или строка символов. Чаще всего это знак !.

Формат команды следующий:

       command<<delimiter<CR>
       ...input lines...<CR>
       delimiter<CR>

Использование ed в shell программе

"Here document" предлагает способ использования ed в shell программе. Предположим вы хотите создать shell программу, которая будет вызывать редактор ed, проводить глобальные изменения в файле, записывать изменения в файл и затем завершать работу с ed. На следующем экране приведено содержание программы ch.text, которая выполняет эти задачи:

     $ cat ch.text<CR>
     echo Type in the filename
     read file1
     echo Type in the exact text to be changed.
     read old_text
     echo Type in the exact new text to replace the above.
     read new_text
     ed - $file1 <<!
     g/$old_text/s//$new_text/g
     w
     q
     !
     $

Обратите внимание на знак - (минус) в команде ed. Эта опция предотвращает распечатку счетчика символов на экране. Обратите также внимание на формат команды ed для глобальной замены: g/$old_text/s//$new_text/g

Программа использует 3 переменные: file1, old_text, new_text. При запуске эта программа использует команду read для получения значений этих переменных. Эти переменные содержат следующую информацию: file - имя файла, который будет редактироваться; old_text - текст, который будет изменен; new_text - новый текст.

Переменные вводятся в программу, here document перенаправляет команду глобальной замены, команду записи и команду завершения команде ed. Запустите программу ch.text. Получите следующий экран:

       $ ch.text<CR>
       Type in the filename
       memo<CR>
       Type in the exact text to be changed.
       Dear John:<CR>
       Type in the exact new text to replace the above.
       To what it may concern:<CR>
       $ cat memo<CR>
       To what it may concern:<CR>
       $

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

Большинство команд shell возвращает коды, которые указывают, успешно ли завершилась команда. Если возвращаемое значение 0(ноль), то команда выполнилась успешно. Коды возврата не печатаются автоматически, но их можно получить как значение специального параметра shell $?.

Проверка кодов завершения

После выполнения в интерактивном режиме команды, вы можете увидеть код завершения при вводе: echo $? Рассмотрим следующий пример:

       $ cat hi
       This is file hi.
       $ echo $?
       0
       $ cat hello
       cat: cannot open hello
       $ echo $?
       2
       $

В первом случае файл hi существует в вашем справочнике и вы имеете разрешение на чтение. С помощью команды cat вы можете распечатать содержимое файла. Результат команды cat: код возврата 0, который вы получите, задав параметр $?. Во втором случае файл либо не существует, либо вы не имеете право на чтение. Команда cat печатает диагностическое сообщение и возвращает код 2.

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

Циклы

Операторы цикла for и while позволяют выполнить команду или последовательность команд несколько раз.

Оператор for

Оператор for выполняет последовательность команд для каждого элемента списка. Он имеет формат:

       for variable<CR>
           in a_list_of_values<CR>
       do<CR>
           command_1<CR>
           command_2<CR>
                .
                .
                .
           last command<CR>
       done<CR>

Для каждой итерации цикла следующий элемент списка присваивается переменной, данной в операторе for. Ссылка на эту переменную может быть сделана в любом месте в командах внутри оператора do. При конструировании каждой секции команд вам необходимо убедиться, что каждому do соответствует done в конце цикла.

Переменная может иметь любое имя. Например, если ваша переменная названа var, то ссылка в списке команд на $var сделает значение доступным. Если оператор in опущен, то значением для var будет набор аргументов, заданный в команде и доступный в специальном параметре $*. Список команд между ключевым словом do и done будет выполнен для каждого значения.

Когда команды будут выполнены для последнего элемента списка, программа будет выполнять строку ниже done.

Оператор while

Оператор цикла while использует 2 группы команд. Он будет выполнять последовательность команд во второй группе (список do ... done) до тех пор пока последняя команда в первой группе (список while) возвращает состояние "истина", означающее, что выражение после do может быть выполнено.

Общий формат оператора цикла while:

       while<CR>
           command_1<CR>
               .
               .
               .
           last command<CR>
       do<CR>
           command_1<CR>
               .
               .
               .
           last command<CR>
       done<CR>

Например, программа enter.name использует цикл while для ввода списка имен в файл. Программа состоит из следующих командных строк:

       $ cat enter.name<CR>
       while
          read x
       do
          echo $x>>xfile
       done
       $

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

    $ cat enter.name<CR>
    echo Please type in each person's name and than a <CR>
    echo Please end the list of names with a <^d>
    while read x
    do
       echo $x>>xfile
    done
    echo xfile contains the following names:
    cat xfile
    $

Обратите внимание, что после завершения цикла программа выполняет команды ниже done.

В первых двух командах echo используются специальные символы, так что вы должны воспользоваться кавычками для отмены специального значения. На следующем экране приведены результаты выполнения программы enter.name:

    $ enter.name<CR>
    Please type in each person's name and than a <CR>
    Please end the list of names with a <^d>
    Mary Lou<CR>
    Janice<CR>
    <^d>
    xfile contains the following names:
    Mary Lou
    Janice
    $

После того, как цикл завершится, программа распечатает все имена, содержащиеся в xfile.

Использование /dev/null

Файловая система имеет файл /dev/null, где вы можете хранить нежелательный вывод. Например, если просто ввести команду who, то система ответит, кто работает в системе. Если вы перенаправите вывод этой команды в /dev/null: who > /dev/null то не получите ответа.

Условные операторы

Оператор if ... then

Команда if говорит shell программе, что нужно выполнить последовательность команд после then, если последняя команда в списке команд конструкции if выполнилась успешно. Конструкции if заканчиваются ключевым словом fi.

Общий формат конструкции if:

       if<CR>
           command_1<CR>
               .
               .
               .
           last command<CR>
       then<CR>
           command_1<CR>
               .
               .
               .
           last command<CR>
       fi<CR>

Например, shell программа search демонстрирует применение конструкции if ... then. Программа search использует команду grep для поиска слова в файле. Если grep выполнилась успешно, то программа отображает найденное слово. Экран будет выглядеть следующим образом:

       $ cat search<CR>
       echo Type in the word and the file name.
       read word file
       if grep $word $file
           then echo $word is in $file
       fi
       $

Эта программа отображает вывод команды grep. Если вы хотите сохранить ответ системы на команду grep в вашей программе, то воспользуйтесь файлом /dev/null, изменив командную строку if на следующую: if grep $word $file > /dev/null<CR>

Теперь выполните команду search. Она ответит только сообщением, указанным после команды echo.

Конструкция if ... then ... else может исполнять альтернативный набор команд, стоящий после else, в случае, если последовательность if является ложью. Формат этой конструкции следующий:

          if<CR>
           command_1<CR>
               .
               .
               .
           last command<CR>
          .linthen<CR>
              command_1<CR>
                .
                .
                .
              last command<CR>
          else<CR>
              command_1<CR>
                .
                .
                .
              last command<CR>
       fi<CR>

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

       $ cat search<CR>
       echo Type in the word and the file name.
       read word file
       if
           grep $word $file > /dev/null
       then
           echo $word is in $file
       else
           echo $word is NOT in $file
       fi
       $

Конструкция case ... esac позволяет выбрать вам один из несколько шаблонов и затем выполнить список команд для этого шаблона. Выражение-шаблон должно начинаться с ключевого слова in, а правая круглая скобка должна быть помещена после последнего символа каждого шаблона. Последовательность команд для каждого шаблона заканчивается двумя знаками ;;. Конструкция case должна быть закончена ключевым словом esac.

Общий формат конструкции case:

       case word<CR>
       in<CR>
           pattern1)<CR>
              command line 1<CR>
                    .
                    .
                    .
              last command line<CR>
           ;;<CR>
           pattern2)<CR>
              command line 1<CR>
                    .
                    .
              last command line<CR>
           ;;<CR>
           pattern3)<CR>
              command line 1<CR>
                    .
                    .
              last command line<CR>
           ;;<CR>
           *)<CR>
              command line 1<CR>
                    .
                    .
              last command line<CR>
           ;;<CR>
       esac<CR>

Конструкция case пытается найти word с шаблоном pattern в первой секции шаблонов. Если поиск удачен, то программа выполняет командные строки после первого шаблона до соответствующих знаков ;;.

Если первый шаблон не найден, то осуществляется переход ко второму шаблону. Если любой шаблон найден, то программа не рассматривает остальные шаблоны, а переходит к команде, следующей за esac. Знак * используется как шаблон для поиска любого word и таким образом дает вам набор команд, который будет выполнен, если никакой другой шаблон не будет найден. Поэтому шаблон звездочка (*) размещается как последний шаблон в конструкции case, чтобы другие шаблоны были проверены первыми. Это поможет вам обнаружить некорректный и неожиданный ввод.

В шаблонах могут использоваться метасимволы *, ?, []. Это обеспечивает гибкость программ.

Рассмотрим пример. Программа set.term устанавливает переменную TERM в соответствии с типом терминала, который вы используете. Применяется следующая командная строка: TERM=terminal_name<CR>

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

Пример.

       $ cat set.term<CR>
       echo If you have a TTY 4420 type in 4420
       echo If you have a TTY 5410 type in 5410
       echo If you have a TTY 5420 type in 5420
       read term
       case term
               in
                   4420)
                        TERM-T4
                   ;;
                   5410)
                        TERM-T5
                   ;;
                   5420)
                        TERM-T7
                   ;;
                   *)
                   echo not a correcr terminal type
                   ;;
       esac
       export TERM
       echo end of programm
       $

Безусловная передача управления

Команда break безусловно останавливает выполнение любого цикла, в котором он встречается и передает управление команде, следующей после ключевых слов done, fi или esac.

В предыдущем примере программы set.term вы можете использовать команду break, вместо echo, чтобы выйти из программы, как приведено в следующем примере:

Пример.

       $ cat set.term<CR>
       echo If you have a TTY 4420 type in 4420
       echo If you have a TTY 5410 type in 5410
       echo If you have a TTY 5420 type in 5420
       read term
       case term
               in
                   4420)
                        TERM-T4
                   ;;
                   5410)
                        TERM-T5
                   ;;
                   5420)
                        TERM-T7
                   ;;
                   *)
                   break
                   ;;
       esac
       export TERM
       echo end of programm
       $

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

Просмотры
Инструменты

Besucherzahler russian mail order brides
счетчик посещений
Rambler's Top100
Лингафонные кабинеты  Интерактивные доски  Интерактивная приставка Mimio Teach