Компания ALT Linux
Опубликован: 14.12.2004 | Доступ: свободный | Студентов: 12209 / 1417 | Оценка: 4.19 / 3.84 | Длительность: 18:18:00
ISBN: 978-5-9556-0019-1
Лекция 11:

Shell как язык программирования и интегратор

< Лекция 10 || Лекция 11: 12345 || Лекция 12 >
Аннотация: Свойства командного интерпретатора как полноценного языка программирования. Командный интерпретатор как средство интеграции процессов системы.
Ключевые слова: Unix, командный интерпретатор, shell, язык программирования, ПО, машина Тьюринга, исполнитель, интегратор (оболочка), файл, текущий каталог, путь, сценарий, AWK, текстовый редактор, имя программы, бит, параметры командной строки, сообщение об ошибке, параметр, индекс, программа, Си, синтаксис, csh, достраивание, управление заданиями, гнёзда командных интерпретаторов, GNU, абстракция, переменная окружения, environment variable, подстановка, expansion, RTFM, окружение, входное имя пользователя, встроенный команды (built-in), смена текущего каталога, ключ, операторные скобки, утилита, индексный дескриптор, команда, код возврата, ложь, истина, оператор выбора, переменная, связывание, оператор цикла, командная строка, цикла, слово, перевод строки, список, место, операции, стандартный ввод, остаток, вывод, конец файла, стандартный вывод ошибок, дескриптор, стандартный вывод, терминал, канал, буфер, поток, подстановка вывода, системный вызов, память, PID, порожденный процесс, запуск, родительский процесс, фоновый процесс, права, общий профиль (system-wide profile), профиль пользователя (user profile), профиль (profile), имя файла, быстродействие, поддержка, условный оператор, перенаправление ввода/вывода

И швец, и жнец

Любой универсальной ОС приходится много возиться с пользовательскими и своими собственными задачами. Лишь небольшая часть этой деятельности может быть запрограммирована раз и навсегда в ядре. Большая часть логики управления задачами и самой системой должна быть доступна администратору в виде проекта, иначе он просто не сможет ни понять происходящее в системе, ни тем более изменять ее. Стоит повнимательнее взглянуть на инструмент, используемый в UNIX для задания алгоритма работы многих частей системы, - на командный интерпретатор, shell. Оказывается, shell отлично себя показывает не только в диалоге с пользователем, но и как исполнитель сценариев, и как средство организации взаимодействия между задачами в системе.

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

С другой стороны, одной алгоритмической полнотой при решении задач в системе ограничиваться нельзя. Скажем, машина Тьюринга [ 9 ] чрезвычайно проста и алгоритмически полна, однако мало кому придет в голову организовывать на основе ее модели диалог с пользователем или управление самой ОС. Здесь следует вспомнить, что shell - еще и исполнитель команд: он запросто общается с UNIX и утилитами. Значит, дополнив его механизмом управляемого взаимодействия команд с системой и друг с другом, мы получим неплохой интегратор (или оболочку - что, собственно, и есть перевод слова shell ).

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

Сценарий

Прежде чем рассмотреть возможности shell под двумя углами зрения, разрешим вот какое затруднение. Допустим, мы написали программу на языке какого-нибудь интерпретатора, например /bin/sh, и записали ее в некий файл, например /home/george/myscript (если /home/george - текущий каталог, можно использовать более короткий путь: myscript ). Как теперь выполнить этот сценарий? Из man sh мы знаем, что для этого можно запустить командный интерпретатор с параметром - именем файла:

$ cat myscript 
echo "Hello, George!"
$ /bin/sh myscript 
Hello, George!

Нельзя ли обойтись без имени программы, которая интерпретирует сценарий? Вообще говоря, нет: в UNIX немало различных интерпретаторов с разнообразным синтаксисом, например обработчик текстов awk, потоковый текстовый редактор sed, универсальные языки программирования python и perl и много чего еще. Во всех этих языках есть возможность вставлять в текст сценария строчные комментарии, которые начинаются с символа "#" и заканчиваются в конце строки. Поэтому, если сценарий начинается с символов " #!", любой из этих интерпретаторов проигнорирует всю первую строку как комментарий. Система же, увидев " #!" в начале файла, понимает, что это сценарий. С третьего символа и до конца строки она читает имя программы, которой отдает этот файл на выполнение. Значит, если первой строкой в /home/george/myscript будет #!/bin/sh, его смело можно делать исполняемым (установить бит использования) и запускать:

$ chmod +x myscript
$ cat myscript
#!/bin/sh
echo "Hello, $1!"
$ ./myscript George
Hello, George!

Строго говоря, после " #!" может стоять что угодно, например имя написанной нами программы с некоторыми обязательными параметрами; UNIX ее запустит и передаст ей в качестве параметров командной строки обязательные параметры (если они есть), затем имя сценария и все, что идет следом (в нашем примере George ). Если же после " #!" будет стоять несуществующий файл, система выдаст сообщение об ошибке:

$ cat myscript
#!/bad/sh
echo "Hello, $1!"
$ ./myscript
./myscript: not found

Обратите, пожалуйста, внимание на то, что из этого сообщения якобы следует, что не найден сам файл сценария. Если не знать подоплеку явления, ситуация кажется подозрительной. Дело в том, что, запуская любую программу, UNIX всегда передает ей один параметр (который имеет индекс 0) - имя этой программы. Но в случае запуска сценария обработчик получит в качестве нулевого параметра не собственное имя, а имя сценария. А когда система этого обработчика не найдет, в сообщении об ошибке он будет упоминаться под новым именем.

Гнезда shell`ов

И еще одно немаловажное замечание. Сначала в UNIX был только один командный интерпретатор, написанный Стивеном Борном (Stephen Bourne), и назывался он просто "оболочка" (т. е. shell, а имя утилиты, для краткости, sh). Это была очень простая маленькая программа, она отлично работала именно как системный интегратор, но во всех остальных ипостасях была довольно слабой. И вот создателям 3BSD пришло в голову, что нужен совершенно новый командный интерпретатор, более удобный при работе в командной строке, с новыми возможностями программирования и с новым синтаксисом, приближенным к языку Си, который и так знаком любому UNIX-программисту. Получившуюся оболочку назвали C shell (за синтаксис команд; имя утилиты - csh), она была намного мощнее старой, там была работа с историей, достраивание имен файлов, управление заданиями; появились массивы и много чего еще.

Однако программировать командные сценарии на csh оказалось... менее удобно, чем на sh. Во-первых, синтаксис языка Си в точности воспроизвести не удалось, возникла путаница; во-вторых, многие системные сценарии уже были к тому времени написаны на shell. Обе эти оболочки дали начало так называемым гнездам - Bourne и C, потому что всякий новый командный интерпретатор проектировался с расчетом на совместимость либо с sh, либо с csh.

Долгое время бытовало мнение, что работать лучше в csh, а сценарии писать - на sh, хотя совмещать два разных языка в одной области деятельности неудобно. С тех пор было создано немало других, еще более мощных sh - и csh -образных оболочек. Они все время дорабатывались, попеременно обгоняя друг друга по охвату возможностей. Пальма первенства принадлежала то bash (Bourne-again shell, детище GNU), то tcsh (международный открытый проект, развивающий csh ), то zsh (также международный открытый проект, но с sh -совместимостью). На сегодня нельзя с уверенностью сказать, какой из них мощнее (хотя документации по zsh больше, чем по bash и tcsh, вместе взятых, раза в два), но устаревшее мнение о sh и csh стоит пересмотреть: теперь в какой оболочке работаешь, на языке той и сценарии пиши.

< Лекция 10 || Лекция 11: 12345 || Лекция 12 >
Andranik Avakian
Andranik Avakian

41. УК РФ и Комментарии (ст. 273)

М. 2000 г. Издательство: ALT Linux, Институт Логики

Уголовный Кодекс РФ и комментарии к нему?

По ссылке открывается сайт документации Linux, раздел Linux Installation and Getting Started

Сергей Петровский
Сергей Петровский

У Вас написано:

ls -dt1 `grep -il отчет *` | head -1

если знания по шелу мне не изменяют, то должно быть:

ls -dt | `grep -il отчет *` | head -1

Марина Дайнеко
Марина Дайнеко
Россия, Moscow, Nope, 2008
Тарас Конюков
Тарас Конюков
Россия