Шрифт:
Интервал:
Закладка:
Большинство стандартных команд ОС реализовано в виде отдельных программ (исключение составляют так называемые встроенные команды[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-процессоры языков программирования, область обработки текстов остается «вещью в себе» и никак не интегрируется с другими областями, осваиваемыми в курсе информатики.