56
Несмотря на имеющиеся различия, все языки имеют сходный синтаксис и построены по одному принципу - каждая строка языка рассматривается как команда с аргументами, требующая немедленного исполнения:
команда [ аргумент_1 аргумент_2 … ] конец_строки
Строка — последовательность слов, разделенных символами пробела или табуляции и заканчивающаяся символами конца строки.
Команда — слово, обозначающее действие:
•встроенная команда исполняется непосредственно интерпретатором;
•имя программы ОС, которую интерпретатор запускает.
Аргумент — слово, интерпретируемое в контексте команды.
Конец_строки — набор:
•управляющих символов языка;
•управляющих слов языка.
Во времена, когда графический интерфейс ОС отсутствовал, командные интерпретаторы были единственным средством взаимодействия человека и ЭВМ. И сейчас они являются таковыми, когда графическая система выходит из строя.
По функциональным возможностям все языки приблизительно одинаковые, хотя в деталях могут различаться синтаксисом. В частности, язык tcl разрабатывался с возможностью использования превдографики, что для своего времени было достаточно перспективно. Их современное совместное существование вызвано:
•силой привычки, авторскими правами и рядом корпоративных интересов;
•наличием достаточно большого количеста ПО, написанного ранее на этих
языках.
Общая проблематика интерпретаторов - увеличение функциональных возможностей shell влечет:
•увеличение его размера и уменьшение скорости его загрузки;
•повышенный расход оперативной памяти компьютера.
Как отмечено выше, термин shell применяется в двух аспектах:
•как расширительное обозначение всех командных интерпретаторов ОС;
•как конкретизация интерпретатора sh (Bourne Shell).
Выбор языка sh обоснован следующими причинами:
•стандартизация языка в рамках проекта POSIX 1003.2 — стандарта мобильных систем;
•современные ядра ОС Linux запускают интерпретатор sh, при обнаружении в корне файловой системы скриптов init или linuxrc;
•интерпретатор bash, используемый ОС Linux, можно рассматривать как прямое функциональное расширение интерпретатора sh.
57
POSIX (Portable Operating System Interface for Unix) — переносимый интерфейс операционных систем UNIX.
POSIX — набор стандартов, описывающих интерфейсы между операционной системой и прикладной программой. Закреплен международным стандартом ISO/IEC 9945 и может использоваться не только для ОС UNIX.
Определим ряд метапонятий, которые shell учитывает в своей работе:
•shell — это программа (утилита или командный интерпретатор) sh, обычно
/bin/sh, который работает в среде ОС: в пользовательском режиме;
•запустить sh может любой процесс, посредством системного вызова exec*();
при этом, sh будет использовать среду ОС, в которой работала вызывающая программа;
•процесс sh может сам порождать необходимое количество дочерних процес-
сов, посредством системного вызова fork(), отслеживая их работу и анализируя их коды завершения;
•нулевой целочисленный код завершения означает нормальное выполнение команды дочерним процессом;
•ненулевой целочисленный код завершения означает ошибочное выполнение
команды дочерним процессом и дополнительно интерпретируется, в зависимости от ситуации и режимов работы sh.
Замечание
Если sh обнаружил синтаксическую ошибку, то выполнение shell прекращается, в противном случае, возвращается код завершения последней выполненной команды.
При запуске, sh как и любая прикладная программа, наследует все ресурсы вызывающего процесса, включая открытые файлы. На рисунке 3.1 показаны ресурсы типового прикладного процесса.
Рисунок 3.1 - Потоки ввода/вывода программы
58 Каждая программа, запущенная в виде процесса на компьютере, имеет:
•один системный ввод;
•два системных вывода.
На уровне файловых дескрипторов, мы имеем:
устройство 0 — устройство ввода; устройство 1 — устройство нормального вывода программы; устройство 2 — устройство вывода ошибок.
На уровне языка С, мы имеем стандартные устройства: stdin — устройство ввода;
stdout — устройство нормального вывода программы; stderr — устройство вывода ошибок.
На уровне языка Java, мы имеем три объекта: java.lang.System.in — объект канала ввода с клавиатуры; java.lang.System.out — объект канала нормального вывода; java.lang.System.err — объект канала вывода ошибок.
Для чтения из потока ввода (обычно клавиатура) используются различные модификации функции read(...).
Для вывода информации в потоки stdout и stderr (обычно консоль) используются различные модификации функций write(…) и print(...).
Особо, следует обратить внимание на номера устройств (целочисленные дескрипторы файлов), которыми интенсивно манипулирует интерпретатор sh.
Например, если процесс закрывает файл с дескриптором 0, а затем открывает новый файл. В результате, дескриптор нового файла будет равен 0 и процесс будет читать данные из файла, как будто он читает с клавиатуры.
Кроме того, sh использует все свойства базовых категорий, определенных понятиями: файл, пользователь и процесс.
Вчастности, обычные файлы подразделяются на:
•бинарные, которые читаются процессом как последовательность байт, имеющих значения от 0 до 255;
•текстовые (символьные), в которых, в зависимости от кодировки, ряд значе-
ний байт или не используются совсем или рассматриваются как управляющие, например: 10 — перевод строки; 13 — возврат каретки.
Интерпретатор sh может использовать текстовые файлы как программы: скрипты или сценарии.
Вчастности, все shell следуют общим правилам:
•символ # используется как комментарий до конца строки;
•сочетание символов #!, расположенных в первой позиции первой строки
текстового файла, рассматривается как команда вызова конкретного интерпретатора shell.
59
Среда выполнения любой программы ОС подразделяется на:
структуру файловой системы ОС, которую программа использует для ввода и вывода данных;
набор файлов конфигурации, которые определяют параметры данных программы или дополнительные данные конфигурации среды исполнения;
системные переменные среды, которые наследуются как из среды родительского процесса, а также создаются или удаляются в процессе работы программы.
Для языка sh, определяется условиями видимости той части файловой системы, которая соответствует пользователю, запустившему shell. В течении работы и запуска, sh использует следующие конфигурационные файлы:
/etc/profile $HOME/.profile /tmp/sh*
/dev/null
Shell использует следующие переменные среды: HOME
Определяет домашний каталог пользователя. Подразумеваемый аргумент команды cd (1) - основной каталог.
PATH
Список имен каталогов для поиска команд. Подобные списки называются списками поиска. Элементы списка разделяются:
двоеточием, для ОС UNIX;
точка с запятой для MS Windows;
точка - означает текущий каталог.
CDPATH
Список поиска для команды cd.
Имя файла, куда будет помещаться почта;
если переменная MAILPATH не определена, shell информирует пользователя о поступлении почты в указанный файл.
MAILCHECK
Интервал между проверками поступления почты в файл, указанный переменными MAIL или MAILPATH.
По умолчанию интервал составляет 600 секунд (10 минут). При установлении значения 0 проверка будет производиться перед каж-дым выводом приглашения.
60
MAILPATH
Список имен файлов, разделенных двоеточием.
Если переменная определена, shell информирует пользователя о поступлении почты в каждый из указанных файлов.
После имени файла может быть указано (вслед за знаком %) сообщение, которое будет выводиться при изменении времени модификации указанного файла (сообщение по умолчанию "You have mail").
PS1
Основное приглашение (по умолчанию "$ ").
PS2
Вспомогательное приглашение (по умолчанию "> ").
IFS
Цепочка символов, являющихся разделителями в командной строке (по умолчанию это пробел, табуляция и перевод строки).
SHACCT
Если значением этой переменной является имя файла, доступного для записи пользователем, shell будет помещать в него сведения о каждой выполняемой им процедуре. Для анализа сведений могут быть применены такие программы, как acctcom (1) и acctcms (1M).
SHELL
При запуске shell просматривает окружение в поисках этой переменной. Если она определена и файловая часть ее значения есть rsh, shell становится ограниченным [см. rsh(1)].
Замечание
Для переменных PATH, PS1, PS2, MAILCHECK и IFS имеются значения по умолчанию. Значения переменных HOME и MAIL устанавливаются командой login(1).
Значения всех переменных можно вывести на консоль командой env.
Окружение [см. environ(5)] - это набор пар (имя, значение), который передается выполняемой программе так же, как и обычный список аргументов.
Shell взаимодействует с окружением несколькими способами:
при запуске, shell просматривает окружение и создает переменную (ключе-вой параметр) для каждого указанного имени, придавая ей соответствующее значение;
если изменить значение какой-либо переменной или создать новую, это не окажет никакого влияния на окружение, если не будет использована команда export для увязывания переменной shell с окружением (см. также set -a);
переменную можно удалить из окружения командой unset.