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

Читать, слущать книги онлайн бесплатно!

Электронная Литература.

Бесплатная онлайн библиотека.

Читать: - на бесплатной онлайн библиотеке Э-Лит


Помоги проекту - поделись книгой:

Рис. 1-57

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

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

Существуют также символы завершения команды «&&» и «||». Их действие связано с понятием кода завершения, возвращаемого каждой командой. Код завершения определяется программой, но обычно успешно выполнившаяся команда возвращает код «0» (ноль), а выполнившаяся с ошибкой – числовое значение кода ошибки. Явную работу с кодами завершения мы обсудим при введении элементов программирования оболочки, а здесь лишь упомянем, что символ завершения «&&» означает, что заданную за ним команду следует выполнить только в случае, если указанная перед ним команда выполнилась успешно, а символ «||» – наоборот, что «правую» команду следует выполнить только при ошибочном завершении «левой» (Рис. 1-58).


Рис. 1-58

1.7 Переменные

До сих пор мы имели дело с параметрами, передававшимися команде в виде аргументов, следующих за именем команды. Команда интерпретирует аргументы исходя их их значений (так, большинство команд считает аргумент, начинающийся с дефиса, ключом) и их позиции (так, команды «cp» и «mv» последний операнд считают целевым файлом или каталогом, а предшествующие – источниками), поэтому аргументы называют еще позиционными параметрами.

В открытых системах существует еще один механизм передачи параметров – переменные. В отличие от аргументов, переменные являются именованными параметрами и их семантика определяется не их позицией и значением, но именем.


Рис. 1-59

В примере на Рис. 1-59 Алиса сначала подает команду «ls» с несуществующим файлом в качестве аргумента и получает сообщение об ошибке на русском языке. Затем она подает ту же команду, предварив ее конструкцией «LC_ALL=C», и получает сообщение о той же ошибке на английском языке.

Конструкция, состоящая из имени переменной и ее значения, разделенных знаком равенства («=») без промежутков, и является определением параметра-переменной для вызываемой команды. В данном случае определяется переменная «LC_ALL», которой присваивается значение «C». Переменная «LC_ALL» является одной из стандартных, ее значение определяет язык и другие национально-специфические особенности интерфейса (эту и несколько других переменных локали мы подробнее рассмотрим ниже).

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

Если нам нужно изменить подобным образом (получать сообщения на английском языке) самой оболочки, следует установить значение переменной такой же конструкцией из имени и значения переменной, разделенных знаком равенства, за которыми не следует никакой команды. Присвоение значения переменной командой само по себе не влияет на поведение вызываемых из оболочки команд, то есть эта переменная им не передается (Рис. 1-60).


Рис. 1-60

Чтобы значение переменной передавалась всем вызываемым командам, ее следует сделать передаваемой (экспортировать ее) командой «export» с именем переменной в качестве аргумента (см. Рис. 1-61).


Рис. 1-61

Установленное значение (вне зависимости от того, экспортировано ли оно) сохраняется до конца сеанса работы с оболочкой, до его переустановки или до уничтожения переменной командой «unset» с именем переменной в качестве аргумента.

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

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

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

Переменная будет раскрыта оболочкой (подобно тому, как оболочка раскрывает значения специальных символов в именах файлов), если указать ее в любом месте любой команды в окружении фигурных скобок «{» и «}» предваренной знаком денежной единицы «$». В большинстве случаев (когда не возникает неоднозначности в интерпретации) фигурные скобки можно опустить (Рис. 1-62).


Рис. 1-62

Получить список переменных, установленных в данный момент времени, можно командой «set» без аргументов, а список экспортированных переменных – командой «env» без аргументов. В типичной системе при запуске оболочки устанавливаются значения нескольких десятков переменных, большинство из которых сразу экспортируются. В примере на Рис. 1-63 эти списки сильно сокращены. С семантикой отдельных переменных мы познакомимся ниже.


Рис. 1-63

Стандартом определен ряд переменных, имеющих фиксированную семантику, значения которых используются стандартными командами. Они представлены в таблице на Рис. 1-64. В большинстве случаев пользователю не нужно устанавливать их значения самостоятельно.


Рис. 1-64

Кроме того, стандарт не рекомендует произвольно переопределять еще ряд переменных: ARFLAGS, CC, CDPATH, CFLAGS, CHARSET, DEAD, EDITOR, ENV, EXINIT, FC, FCEDIT, FFLAGS, GET, GFLAGS, HISTFILE, HISTORY, HISTSIZE, IFS, LDFLAGS, LEX, LFLAGS, LINENO, LISTER, LPDEST, MAIL, MAILCHECK, MAILER, MAILPATH, MAILRC, MAKEFLAGS, MAKESHELL, MANPATH, MBOX, MORE, MSGVERB, PROC, OLDPWD, OPTARG, OPTERR, OPTIND, PAGER, PPID, PRINTER, PROCLANG, PROJECTDIR, RANDOM, SECONDS, TERMCAP, TERMINFO, USER, VISUAL, YACC, YFLAGS. Некоторые из них используются самой оболочкой, некоторые – стандартными командами, а некоторые – прикладными и инструментальными программами.

Локаль, «и17я» и «л9я»

Локалью («locale» – «местонахождение») называется совокупность переменных, управляющих поведением оболочки, команд и других программ в части языковых и национально-культурных особенностей. Локалью также называются и значения, которые принимают эти переменные (кроме NLSPATH).

В любой стандартной ОС определены (совпадающие) локали «POSIX» и «C». Эта локаль называется «системной» и во всех известных нам системах она соответствует соглашениям, принятым в США48.

В ОС может быть также определено произвольное количество локалей, именуемых следующим образом: двухбуквенное ИСО-сокращение названия страны, за которым слитно следует знак подчеркивания «_» и – слитно же – двухбуквенное ИСО-сокращение названия языка. Далее могут следовать (также слитно) точка и наименование кодовой таблицы. Для русского языка и российских культурных особенностей значением локали будет «ru_RU.KOI8-R» или «ru_RU.ISO8859-5».

Текущую локаль можно узнать, подав команду «locale». Обычно всем переменным локали (кроме NLSPATH), перечисленным на Рис. 1-65, присваивается одно и то же значение (это можно сделать, установив значение всего лишь одной переменной, LC_ALL). Однако бывают и другие случаи: например, иностранный сотрудник или студент может предпочесть сообщения и диалоги на родном языке, а остальные национально-культурные параметры – соответствующими стране пребывания.


Рис. 1-65

Интернационализованной называется программа (включая стандартные команды), корректно изменяющая свое поведение в соответствии с переменными локали.

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

Для длинных слов «localization» и «internationalization» иногда даже в формальных документах используются сокращения «l10n» и «i18n» (цифры между первой и последней буквой образуют число пропущенных букв).

Стандартный набор команд (и многие дополнительные программы), входящие в состав популярных дистрибутивов открытых систем, в массе своей интернационализованы, но с русской локализацией ситуация весьма неоднозначна. Вы столкнетесь с ситуациями, когда перевода того или иного ресурса (например, сообщений об ошибках и диагностики) для определенной программы не окажется – корректно интернационализованная программа «откатится» к системной локали «C»49.

Вы также можете столкнуться и с некорректно интернационализованными программами (такое случается с прикладным кодом, перенесенным с альтернативных платформ, или разработанным без оглядки на локаль), которые игнорируют локаль, ведут себя странно или отказываются работать при локали, отличной от «C»50.

К сожалению, при применении наиболее популярного сегодня «IBM PC-совместимого» оборудования (т.е. компьютеров на основе процессоров архитектуры IA-32) реальная локализация аппаратно-программной системы не сводится к установке локали. Для возможности ввода нелатинских символов необходимо назначить код переключения систем письменности какой-либо клавише. Кроме того, чтобы терминал отображал нелатинские символы в текстовом режиме, в видеоадаптер должен быть подгружен соответствующий шрифт (при применении эмулятора терминала в графическом режиме этой проблемы нет). Стандартного способа осуществления этих действий нет, каждая ОС решает эти задачи по-своему.

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

Работать с текстами, включающими одновременно большее количество символов, можно, используя кодовые таблицы Юникод (стандарт ИСО/МЭК 10646) и кодировку UTF8. Однако не все ОС поддерживают корректную работу текстовых утилит при переменной длине символов. Кроме того, применять при этом вшитый знакогенератор видеоадаптера уже не представляется возможным, и для терминального режима нужен встроенный в драйвер программный знакогенератор. Проблемы, связанные с UTF8-локалью, должны быть решены в современных ОС в течение ближайших лет.

Команда как файл и переменная $PATH

Обратите внимание на переменную $PATH (у Алисы ее значение оказалось равным «/home/alice/bin:/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/usr/games»). Значение переменной $PATH интерпретируется оболочкой как список имен каталогов, разделенных двоеточиями. Когда оператор вводит команду, оболочка просматривает эти каталоги в поисках исполняемого файла с именем, совпадающим с именем введенной команды.

Большинство стандартных команд ОС реализовано в виде отдельных программ (исключение составляют так называемые встроенные команды51). Чтобы оболочка нашла и запустила соответствующую программу, путь к ней (т.e. имя каталога, в котором содержится эта программа) должен содержаться в списке, составляющем переменную $PATH. Текущий каталог не исключение – чтобы поиск программы осуществлялся и в нем, он должен в явном виде присутствовать в этом списке52.


Рис. 1-66

В приведенном на Рис. 1-66 примере Алиса проверяет значение $PATH, затем добавляет в начало списка текущий каталог и убеждается, что значение переменной приняло искомую форму. (Этот пример демонстрирует особенности экранирования, выполняемого двойными кавычками. Они экранируют пробелы, но, в отличие от апострофов, не мешают раскрытию специальных символов и имен переменных).

Хотя стандартом не определены каталоги, в которых содержатся исполняемые файлы команд, в большинстве современных ОС основным таким каталогом является «/usr/bin/».

Добавление в PATH текущего каталога считается весьма легкомысленным; по крайней мере, суперпользователь никогда не должен этого делать53. Удобным является присутствие в PATH каталога «~/bin/» (в нашем примере «/home/alice/bin/»). В него пользователь может помещать собственные сценарии и другие программы.

Команду, соответствующую программе, чей код размещен вне путей, перечисленных в PATH, можно издать, указав полное или относительное имя файла (например, команда «./моя_программа -o» запустит программу, содержащуюся в файле «моя_программа» в текущем каталоге). Файл должет быть исполняемым.

1.8 Конвейер

Помимо использования символов завершения («&», «;», «&&» и «||») и скобок «(» и «)», в открытых ОС имеется еще один механизм объединения простых команд в группу – конвейер54.

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

В следующем примере Алисе по каким-то причинам нужно получить пронумерованный список файлов в одном из каталогов. У команды «ls» нет соответствующего ключа, хотя есть ключ «-1» (единица), позволяющий осуществить вывод списка в «коротком» формате по одному файлу на строку. Но в системе имеется стандартная команда «nl», выводящая строки ввода, предваренные их номерами.

Алиса может перенаправить вывод команды «ls -1» во временный файл, затем перенаправить ввод команды «nl» из того же файла и, наконец, удалить его (Рис. 1-67).


Рис. 1-67

Это достаточно громоздко; кроме того, в вывод попало и имя самого временного файла, что в планы Алисы не входило55.

Конвейер – это соединение двух или более команд символом «|» («вертикальная черта», «пайп»). При связывании команд конвейером, вывод указанной слева становится вводом указанной справа, без каких-либо временных файлов (Рис. 1-68).


Рис. 1-68

В конвейер могут быть связаны и более двух команд. В примере на Рис. 1-69 Алиса передает, как и ранее, вывод команды «ls» команде «nl», а вывод «nl» передает команде «sort -r», которая (с этим ключом) выводит свой ввод, отсортированный в обратном порядке.


Рис. 1-69

Ввод (но не вывод) первой команды в конвейере может быть перенаправлен из файла посредством символа «<», а вывод (но не ввод) последней – перенаправлен в файл или в конец файла символами «>», «>>». Перенаправлять стандартный ввод или вывод команд, окруженных символами конвейера с обеих сторон, бессмысленно56, хотя можно (и бывает полезно) перенаправить в файл вывод их ошибок («2>» или «2>>»).

В некоторых случаях бывает все-таки необходимо вывести «сечение» конвейера в определенной точке. Для этого служит команда «tee», копирующая ввод в вывод и параллельно записывающая его в файл, имя которого указано в качестве ее аргумента. При необходимости осуществить вывод на терминал, необходимо в явном виде указать его имя (/dev/tty) (см. Рис. 1-70).


Рис. 1-70

Приведенный пример повторяет уже встречавшуюся цепочку из трех команд, но итоговый вывод перенаправлен в файл «временный», а между командами «nl» и «sort» вставлена команда «tee /dev/tty», копирующая поток конвейера на текущий терминал. На терминал, соответственно, выводится последовательность строк после их нумерации, но до ее обратной сортировки.

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

Введение механизма конвейера и его эффективная реализация в ранних версиях ОС «Юникс» революционализировали практику программирования, в том числе, системного. Именно благодаря наличию этого механизма на уровне ОС стала возможна аккуратная декомпозиция реальных задач на относительно простые фрагменты-утилиты.

В «доюниксовых» системах пришлось бы предвидеть возможность того, что какой-нибудь Алисе понадобится нумерация строк и обратная сортировка списка файлов в каталоге, и включать соответствующие ключи в реализацию команды «ls». Что еще хуже, их реализацию пришлось бы включать в каждую программу, построчно обрабатывающую тексты (или убедить Алису в том, что «на самом деле такая возможность не нужна»)57.

Декомпозицией задач и предоставлением «тезауруса» отдельных команд вкупе с механизмами их связывания и объясняется простота и элегантность открытых ОС. Поскольку большинство команд вводят и/или выводят текст, существует практически неограниченная возможность их комбинации, отвечающей как предвиденным, так и непредвиденным разработчиками ситуациям.

Наличие таких механизмов и «дешевизна» (в терминах потребления компьютерных ресурсов) их применения обусловили складывание вокруг открытых систем культуры разработки (не только системной, но и прикладной), частью которой являются принципы:

1) минимизации функциональности отдельных программ,

2) простоты форматов ввода-вывода и

3) реализации программ в виде фильтров (то есть, преобразующих стандартный ввод в стандартный вывод) везде, где это возможно.

Наиболее очевидным примером реализации этих принципов является набор текстовых утилит, входящих в стандарт, некоторые из которых («cat», «nl», «sort») были уже бегло рассмотрены нами.

1.9 Элементы обработки текста

Обработка «плоских» (неразмеченных) текстов – одно из первых (после собственно вычислительных задач и управления приборами), очень важное и хорошо исследованное приложение компьютера.

Работа с текстами критична для многих других пользовательских приложений. Электронная почта – это текст. Форматы разметки, посредством которых представлены форматированный текст, векторная графика, ноты и т.п. (практически все данные, за исключением растровой графики, волнового представления звука и видеодорожек) – в основе своей также текст.

Даже картинки и звуковые файлы, размещенные в WWW, передаются незаметно для пользователя между машинами в закодированной текстом форме, хотя в данном случае текст и не является «собственной» формой представления данных.

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

Эффективная работа с текстом критична и для развития самих вычислительных и коммуникационных систем, поскольку сами программы в исходной своей форме – тексты. Для программ на интерпретируемых языках тексты являются и исполняемой формой, так что такие программы – тексты вдвойне (а типичная стандартизованная ОС почти наполовину состоит из «сценариев», т.е. программ, написанных на интерпретируемых языках).

(Хотя существуют и исключения. Например, электронные таблицы – специфические программы (определяющие порядок вычислений и способ представления их результатов) – представляют собой размеченный, а не «плоский» текст. В некоторых случаях файлы настроек – тоже программы в широком смысле этого слова – представлены не текстом, а базой данных более сложной структуры. Программы с графическим интерфейсом могут содержать значительные фрагменты, первичной формой представления которых является нетекстовая.)

Приемы работы с текстом – неотъемлемая часть компьютерной грамоты, но слишком часто она оказывается не освоенной вовремя. К сожалению, зачастую в курсе средней школы знакомство с обработкой «плоских» текстов ограничивается встроенными редакторами в среде программирования и электронно-почтовой программе, а навыки – простейшими приемами набора и исправления. Более абстрактные и всеобщие операции изучаются как часть word-процессинга, и хотя иногда при этом и демонстрируются возможности встроенных в word-процессоры языков программирования, область обработки текстов остается «вещью в себе» и никак не интегрируется с другими областями, осваиваемыми в курсе информатики.

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

С некоторыми командами потоковой обработки (такими, как «cat», «nl») мы коротко познакомились выше.

Размеченный и «плоский»

Водораздел между текстовыми редакторами и word-процессорами58, проходит по способу отображения размеченного (имеющего некоторые атрибуты, такие, как цвет, начертание и кегль (размер) символов, выключка (выравнивание) и расположение абзацев, оформление страницы и т.п.) текста.

Word-процессор определенным образом интерпретирует разметку, визуализуя указанные атрибуты.

Текстовый редактор отображает размеченный текст «как есть» (с тегами разметки), хотя он вполне может быть «в курсе» синтаксиса языка разметки (если текст размечен, например, на языке XML, HTML или TeX) или даже самого текста (например, синтаксиса языка программирования) и каким-то образом его учитывать (например, расцвечивать теги разметки HTML или зарезервированные слова Pascal). В принципе, он может быть «в курсе» синтаксиса, грамматики и лексики даже естественного языка, хотя для работы с естественными языками «плоский», неразмеченный текст используется все реже, или, по крайней мере, неразмеченный текст все реже используется как первичная форма представления текста на естественном языке.



Поделиться книгой:

На главную
Назад