Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #100, АПРЕЛЬ 2007 г.

Шелл шеллу рознь

Евгений «j1m» Зобнин

Хакер, номер #100, стр. 110

(j1m@list.ru)

Командные интерпретаторы: сравнительно-историческая эпопея

За всю историю операционной системы UNIX для нее было создано огромное количество различных командных интерпретаторов. Некоторые из них предопределили дальнейшее развитие шеллов, единицы стали стандартом, а многие умерли сразу после рождения. Одни продолжают развиваться и сегодня, другие уже не поддерживаются. Как же сориентироваться и сделать правильный выбор?

Thompson shell

История командных интерпретаторов UNIX началась, как и следовало предполагать, вместе с рождением самой операционной системы. Шелл, вошедший в поставку первой редакции UNIX и написанный Кэном Томпсоном (Ken Thompson), был по сегодняшним меркам очень простым и примитивным. Все, что он мог делать, - это читать команды, введенные пользователем, и запускать их на исполнение. Об интегрированном скриптовом языке, автодополнении и истории команд, так привычных сегодняшнему пользователю UNIX, никто тогда даже и не думал. Хотя возможность перенаправления вывода команды в файл уже была реализована.

В шелл третьей версии UNIX по предложению Дугласа Макилроя (Douglas McIlroy) была добавлена возможность перенаправления вывода одной команды на вход другой, а в четвертой версии она обрела свой нынешний облик (оператор «|»). Также были добавлены операторы if и goto, выполненные как отдельные программы.

Разработчики дистрибутива Programmer's Workbench UNIX модифицировали шелл Томпсона, чтобы сделать его более пригодным для программирования. В результате они выпустили PWB shell (или Mashey shell, по имени главного разработчика).

Boue shell

Многочисленные ограничения командного интерпретатора Томпсона не позволяли применять его в качестве полноценного скриптового языка и использовать для автоматизации работы. Этот факт волновал не только самих пользователей, но и программистов, привыкших перекладывать свою работу на плечи «железного помощника». И кто знает, сколько бы продолжалась такая несправедливость, если бы в один прекрасный день Стивен Борн (Stephen Boue) не сел за терминал и не переписал стандартный шелл UNIX.

Именно перу Стивена Борна принадлежит тот синтаксис скриптового языка, который мы видим чуть ли не ежедневно, работая в консоли или программируя скрипты. И сколько бы пользователи не ругали все эти done, fi, esac и другие синтаксические причуды, Борн позволил UNIX сделать большой шаг вперед и на много лет предопределил направление развития командных интерпретаторов.

Основными нововведениями Борна стали:

*оператор ветвления if ... then ... elif ... else ... fi;

*оператор цикла for ... do ... done;

*оператор выбора case ... in ... esac;

*переменные окружения;

*подстановка результата исполнения команды ('$(...)');

*возможность перенаправления файлового дескриптора 2 (2>), позволяющая разделять поток данных и поток ошибок.

Компания AT&T включила командный интерпретатор Борна в базовую поставку седьмой версии UNIX, полностью заменив им шелл Томпсона. Позднее Кэннет Алквист (Kenneth Almquist) создал свободный вариант шелла Борна под названием Almquist shell (ash). Сегодня он используется в Debian, Ubintu и некоторых BSD-системах как интерпретатор стартовых скриптов, а также входит в состав пакета BusyBox, предназначенного для использования во встроенных версиях Linux.

C shell

Можно было бы предположить, что после того как Стивен Борн расширил шелл Томпсона до полноценного скриптового языка программирования, история командных интерпретаторов пойдет эволюционным путем и завершится где-нибудь на отметке zsh. Но все повернулось совершенно иначе. В 1979 году небезызвестный Билл Джой (Bill Joy), активный разработчик BSD UNIX и создатель редактора vi, сделал свою версию командного интерпретатора со встроенным скриптовым языком и назвал его C shell (csh).

C shell не унаследовал нововведений, сделанных Стивеном Борном, потому как базировался на коде командного интерпретатора шестой версии UNIX, который был хоть и расширенным, но все же шеллом Томпсона. Скриптовый язык csh не уступает шеллу Борна по мощности, но отличается синтаксисом. В то время как Борн скопировал все основные операторы с языка Algol68, Билл Джой использовал в качестве макета язык Си, вероятно, руководствуясь своими предпочтениями и предпочтениями других пользователей BSD UNIX.

Некоторым пользователям синтаксис C shell может показаться более правильным и очевидным, нежели синтаксис шелла Борна, но на самом деле это не так. В начале 90-х C shell подвергся большой критике за свою двусмысленность и немногословность интерпретатора, останавливающего выполнение скрипта, но не сообщающего никаких подробностей о том, что же все-таки произошло. Порой скрипты csh работали совсем не так, как этого ожидал пользователь. Также встречались ситуации, когда интерпретатор отбраковывал, казалось бы, непротиворечивые строки кода.

Но все-таки Биллу Джою нужно отдать должное. В csh было сделано несколько нововведений, которые не только стали частью всех современных командных интерпретаторов UNIX, но и вошли в стандарт POSIX. Среди них:

*расширение пути до домашнего каталога (символ «~»);

*псевдонимы (команда alias);

*управление заданиями (фоновое исполнение команды с помощью указания символа «&» после команды и встроенная команда jobs);

*работа с историей (повторное выполнение команды с помощью указания перед ней символа «!» и навигация по истории команд);

*массивы;

*математические операции.

C shell вошел в поставку 4.1BSD и до сих пор остается базовой частью всех ее потомков, в том числе FreeBSD и OpenBSD.

TENEX C shell

Кэн Грир (Ken Greer), вдохновленный возможностями командного интерпретатора операционной системы TENEX, создал свою, расширенную версию C shell и назвал ее TENEX C shell (tcsh). Основной инновацией шелла стала одна из самых востребованных сегодня возможностей - автодополнение путей и команд. Именно эта особенность сделала шелл TENEX таким привлекательным и, как следствие, стала главной причиной его популярности. Несколько позднее в tcsh была добавлена другая не менее интересная и востребованная возможность - редактирование командной строки. Теперь можно было стереть введенную строку, заменить в ней слова, переместить курсор в начало или конец строки (большинство современных командных интерпретаторов используют библиотеку readline для выполнения таких манипуляций).

По мере развития tcsh в него добавлялось все больше новых функций. Сегодняшняя версия этого шелла обладает такими возможностями, как:

*редактирование командной строки с поддержкой стилей vi и emacs;

*программируемое автодополнение (шелл можно настроить так, чтобы по нажатию <Tab> дополнялись не только имена команд и пути, но и, например, поддерживаемые командой флаги);

*проверка правописания имен файлов, команд и переменных;

*расширенный механизм навигации по каталогам (команды pushd, popd, dirs);

*периодические события (например, отложенное во времени исполнение команды или «сброс» пользователя по истечении тайм-аута).

*возможность указания в приглашении различной полезной информации (текущий каталог, время, дата).

Это лишь некоторые из функций tcsh. По всем признакам это современный и удобный в использовании командный интерпретатор, развитие которого продолжается по сей день.

Ko shell

На tcsh история командных интерпретаторов с Си-подобным синтаксисом фактически заканчивается, и мы возвращаемся к потомкам шелла Борна. В начале 80-х Дэвид Корн (David Ko), один из сотрудников Bell Labs, начал работу над командным интерпретатором, расширяющим возможности шелла Борна. По сложившейся традиции, новый шелл был назван в честь создателя - Ko shell (ksh).

В первую версию ksh вошло несколько изменений, облегчающих создание скриптов, а также скопированные из csh (по просьбам пользователей) функции работы с историей. В шелле Корна впервые появилась возможность редактирования командной строки (стили emacs и vi), позже она была перенесена в tcsh. Кроме того, шелл Корна позволял использовать клавиши «вверх» и «вниз» для навигации по истории. Версия, выпущенная в 1986 году, обрела полную совместимость с мультибайтовыми кодировками.

Версия ksh88 стала частью UNIX System V Release 4 и была одобрена для включения в стандарт POSIX. В последнем релизе ksh, выпущенном в 1993 году, появилась возможность изменения функций горячих клавиш, а также множество дополнений к скриптовому языку. В частности, интерпретатор ksh93 научился работать с ассоциативными массивами (хэш, в терминологии Perl), выполнять операции над числами с плавающей точкой, динамически загружать встроенные команды, работать с «активными» и «смешанными» переменными (это придавало переменным некоторые черты «объектов»). Также в эту версию ksh была добавлена полностью совместимая со стандартом ANSI-C функция printf.

Оригинальная версия ksh до 2000 года оставалась закрытой, и поэтому появилось несколько совместимых командных интерпретаторов, распространяемых свободно. В их число вошли pdksh (Public Domain Ko shell), bash и zsh.

Boue again shell

Boue again shell (bash) - это командный интерпретатор, созданный Браином Фоксом (Brian Fox) в рамках проекта GNU. Вначале он позиционировался как свободная замена закрытому ksh, но позднее вырос в независимый продукт с несколькими оригинальными нововведениями. Bash полностью совместим с шеллом Борна и стандартом POSIX. Многие его возможности взяты из ksh и csh. Редактирование командной строки, история команд, фоновое исполнение заданий, стек каталогов (команды pushd и popd), подстановка результата исполнения команды ('$(...)'), автодополнение имен команд и каталогов, встроенная поддержка арифметических операций ('((...))') - все это есть в bash.

Кроме того, bash обладает несколькими уникальными характеристиками, такими как, например, одновременное перенаправление выходного потока и потока ошибок (&&gt;), перенаправление стандартного входа из строки (<<< 'строка'), открытие и закрытие файлов (exec 3 <file; exec 3 <&-) и работа с сокетами (exec 3<>/dev/tcp/www.host.ru/25; echo -e "HELLO www.myhost.ru" >&3). В третью версию bash были добавлены встроенный отладчик скриптов, возможность сравнения с регулярным выражением ([[ строка =~ шаблон ]]) и новый вид замен (конструкция «{x..y}» заменяется строкой из чисел от x до y).

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

Z shell

«Перенесите большой и тяжелый кухонный комбайн, способный заменить всю остальную бытовую технику на Вашей кухне, в мир командных интерпретаторов - и Вы получите Z shell» - с таких слов должна начинаться web-страница программы zsh.

Z shell (zsh) был написан в 1990 году Полом Фолстадом (Paul Falstad) во время его учебы в университете Принстона. Имя для командного интерпретатора он выбрал практически случайно, использовав логин zsh, которым пользовался ассистент его учителя Zhong Shao для входа в операционную систему.

Описать zsh, даже поверхностно, в таком маленьком обзоре практически невозможно. Zsh - это огромный «комбайн», которым можно заменить все остальные шеллы, представленные в этой статье. Он может быть подобен sh, csh или tcsh. Он может быть полностью совместим с bash, а может быть не похож ни на что. Можно применять zsh как ftp- или irc-клиент, писать с его помощью серверные программы, обрабатывающие запросы клиентов, или вовсе не знать о его мощи и использовать как обычный командный интерпретатор. По заложенному в программу потенциалу и многогранности областей применения zsh сравним разве что с редактором emacs.

Кроме эмуляции функциональности всех рассмотренных выше командных интерпретаторов, zsh также порадует пользователя следующими возможностями:

*очень гибкий механизм программируемых автодополнений (в теории, zsh можно научить дополнять по клавише <Tab> все что угодно);

*расширенные маски файлов ('*' и '?' - это лишь начальный уровень, по меркам zsh);

*расширенные функции работы с переменными и массивами;

*расширенный механизм редактирования командной строки (zsh использует собственный вариант readline, названный zle, который делает редактирование строк более гибким);

*расширенный механизм настройки приглашения (zsh позволяет, например, поместить часть приглашения в правую сторону экрана);

*единая история команд для всех запущенных экземпляров zsh (можно быть уверенным, что история одного экземпляра zsh не перекроет историю другого);

*загружаемые модули, позволяющие расширять набор встроенных команд без модификации кода (например, модуль zftp для работы с протоколом ftp добавляет в набор одноименную команду);

*zsh чрезвычайно конфигурируемый, практически любой его параметр поддается настройке.

Практически неограниченная мощь zsh одновременно является и его недостатком. Это очень трудный в освоении командный интерпретатор (имеется в виду освоение всех функций), полное описание которого занимает больше 300 страниц формата A4.

Friendly interactive shell

Описанные выше шеллы в большинстве своем достаточно сложны для освоения новичками и не могут быть отнесены к разряду дружелюбных к пользователю программ. Fish, созданный Axel Liljencrantz (не возьмусь за перевод этого имени), выгодно отличается от них в этом отношении. Этот командный интерпретатор не просто наиболее близок к определению «простой в использовании шелл», но и представляет несколько функций, интересных даже профессионалам.

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

Хронология развития командных интерпретаторов UNIX

Thompson shell (1971 год, первая версия UNIX, Ken Thompson);

Boue shell, или sh (1977 год, Version 7 UNIX, Stephen Boue);

C shell, или csh (1979 год, 4.1BSD, Bill Joy);

Tenex C shell, или tcsh (конец 70-х, BSD UNIX, Ken Greer);

Ko shell, или ksh (1983 год, AT&T UNIX, David Ko);

Boue again shell, или bash (1987 год, POSIX, Brian Fox);

Z shell, или zsh (1990 год, POSIX, Paul Falstad);

Friendly interactive shell, или fish (2005 год, POSIX, Axel Liljencrantz).

Особенности оболочки ash

Оболочка ash представляет собой одну из самых маленьких оболочек, доступных в *nix (за счет малых требований к памяти и дисковому пространству, по сравнению с другими sh-совместимыми оболочками). Этот командный интерпретатор имеет 24 встроенные команды и 10 различных опций командной строки. Обычно ash используется при загрузке Linux в однопользовательском режиме, в защищенном режиме или при загрузке дискетных версий Linux. Также с ее помощью можно проверять скрипты на sh-совместимость. В NetBSD в качестве /bin/sh работает именно ash.

INFO

Shell (наиболее близкий аналог в русском языке – оболочка) - программное обеспечение, создающее интерфейс между пользователем и операционной системой. Shell может быть как текстовым (CLI, командный интерпретатор), так и графическим (GUI). К первому типу можно отнести командные интерпретаторы sh, bash, zsh, второй составляют комплексы программ, обеспечивающих графическое окружение пользователя, такие как KDE, Gnome и XFCE.

Для пользователя современных UNIX-подобных операционных систем установка, удаление или замена командного интерпретатора - обычное дело. Но так было не всегда. Шелл, исполняемый как отдельный процесс, впервые появился в ОС Multics, предшественнице UNIX. В более ранних операционных системах он был встроен в ядро.

WWW

jneitzel.sdf1.org/osh/

www.in-ulm.de/~mascheck/various/ash

www.tcsh.org

www.koshell.com

www.gnu.org/software/bash/bash.html

www.zsh.org

fishshell.org

Содержание
ttfb: 49.138069152832 ms