Оболочка предоставляет множество механизмов для создания индивидуальных условий для работы. Как говорилось выше, оболочка═ — это больше, чем интерпретатор команд. Оболочка является также мощным языком программирования. Методика написания скриптов командной оболочки═ — отдельная большая тема; здесь будут даны лишь отдельные способы, с помощью которых можно привлечь развитые возможности командной оболочки для облегчения работы в системе Linux.
Как указывалось выше, при выполнении скриптов различные оболочки используют различный синтаксис. Например, оболочка tcsh использует синтаксис, похожий на язык программирования C, тогда как оболочка bash использует синтаксис другого типа. В данном разделе эти различия не будут очень существенными, однако все же предполагается, что скрипты будут исполняться оболочкой bash.
Скрипты командной оболочки
Допустим, что вам часто приходится выполнять некоторую последовательность команд, и вы хотите сократить время ввода команд, сгруппировав их в одну «команду». Например, для объединения файлов chapter1, chapter2 и chapter3 в файл с именем book, выдачи количества строк и печати этого файла будет использоваться последовательность из трёх команд:
/home/larry# cat chapter1 chapter2 chapter3 $>$ book /home/larry# wc -l book /home/larry# lp book
Вместо того, чтобы вводить эти три команды с клавиатуры, их можно объединить в скрипт командной оболочки (shell script). Скрипт, который будет исполнять эти три команды, будет выглядеть примерно так:
#!/bin/sh # Скрипт для создания и печати книги cat chapter1 chapter2 chapter3 > book wc -l book lp book
Скрипты командной оболочки являются обычными текстовыми файлами; их можно создавать текстовыми редакторами, такими как emacs или vi.
Рассмотрим этот скрипт. Первая строка #!/bin/sh идентифицирует этот файл как скрипт и сообщает командной оболочке, как его исполнять. Эта строка сообщает оболочке, что этот файл надо передать на исполнение программе /bin/sh, т. е. самой программной оболочке. Данная строка будет важной потому, что в большинстве систем Linux файл /bin/sh содержит оболочку типа bash, например, bash, и данная строка принуждает работающую в системе оболочку выполнять этот скрипт, используя синтаксис, принятый в оболочке bash (а не синтаксис на основе языка C, к примеру). Даже если в качестве стартовой оболочки (login shell) используется tcsh, с данной строкой этот скрипт будет выполняться оболочкой bash.
Вторая строка является комментарием (comment). Комментарии начинаются символом # и продолжаются до конца строки. Командная оболочка комментарии игнорирует. Обычно комментарии используются для того, чтобы указывать назначение скрипта и делать его более понятным.
Остальные строки скрипта являются обычными командами, такими же, как если бы их вводили непосредственно при работе с командной оболочкой. Оболочка читает каждую строку скрипта и выполняет её точно так же, как если бы эта строка вводилась на приглашение командной оболочки.
Для скриптов существенными являются права доступа. Если вы создаёте скрипт командной оболочки, вам надо обеспечить, чтобы у вас были права на его исполнение. Когда создаются текстовые файлы, обычно по умолчанию право на исполнение файлу не даётся, и это право надо назначить файлу явно. Процедура установки и изменения прав доступа подробно обсуждалась выше. Для краткости мы укажем, что в данном случае, если скрипт записан в файл makebook, можно использовать команду
/home/larry# chmod u+x makebook
Эта команда даст вам право на исполнение скрипта в файле makebook.
Теперь для исполнения всех команд скрипта достаточно одной команды
/home/larry# makebook
Переменные оболочки и окружение
Подобно большинству языков программирования, командные оболочки позволяют создавать переменные (variables). Переменная═ — это просто некоторые данные, которым дано имя.
Оболочка tcsh, а также другие оболочки с синтаксисом, основанным на языке C, для создания переменных используют механизм, отличный от описываемого здесь. Приводимые примеры относятся к оболочке типа bash, например, bash. Подробности можно найти в экранной документации к программе tcsh.
В следующем примере показывается, как переменной присваивается значение оператором = и как можно извлекать это значение, приписывая символ $ перед именем переменной.
/home/larry# foo="hello there"
Переменной foo присваивается значение hello there. Теперь это значение можно извлечь из переменной, приписав перед именем символ $. Например команда
/home/larry# echo $foo hello there /home/larry#
даст те же результаты, что и команда
/home/larry# "hello there" hello there /home/larry#
Такие переменные являются внутренними переменными оболочки, что означает, что к ним имеет доступ лишь командная оболочка. Это может быть полезно при написании скриптов: если нужно, например, проследить за файлом с некоторым именем, это имя можно присвоить некоторой переменной и действовать, как было показано выше. Вывести список всех созданных переменных оболочки можно командой set.
Кроме этого, оболочка позволяет экспортировать (export) переменные во (внешнее) окружение (environment). Окружение представляет собой набор переменных, к которым имеют доступ все исполняемые команды. После того, как переменная, созданная внутри командной оболочки, экспортирована, она также становится частью окружения. Для экспортирования переменных используется команда export.
Здесь опять имеются различия между командными оболочками bash и tcsh. Если используемой оболочкой является tcsh, то для установки переменных окружения используется другой синтаксис (а именно — команда setenv). Более подробно об этом написано в экранной документации к программе tcsh.
Окружения играют очень важную роль в системе UNIX. Задавая некоторые переменные окружения, которые известны определённым командам, можно конфигурировать эти команды.
Приведём простой пример. Переменная окружения PAGER используется командой man и указывает, что надо выводить экранную документацию по одному экрану за один раз. Если установить значением переменной PAGER имя некоторой команды, то она будет использоваться для вывода документации на экран вместо команды more, используемой по умолчанию.
Установим, например, для переменной PAGER значение cat. При этом вывод команды man станет выводиться на экран сразу целиком, а не страница за страницей. Продемонстрируем это. Сначала переменной присваивается значение:
/home/larry# PAGER=cat
Потом переменную PAGER надо экспортировать.
/home/larry# export PAGER
Теперь переменная PAGER стала частью окружения. Можно попробовать ввести команду man ls. При этом экранная документация целиком промелькнёт по экрану, вместо того, чтобы выдаваться экран за экраном с приглашением.
Изменим теперь значение переменной PAGER на more. Теперь для вывода документации будет использоваться команда more:
/home/larry# PAGER=more
Заметим, что теперь после изменения значения переменной PAGER команду export использовать не нужно: переменная экспортируется один раз, и все изменения в ней, сделанные после этого, автоматически распространяются на окружение.
Для того, чтобы оболочка не трактовала некоторые символы как специальные, часто строки приходится заключать в кавычки. Например, для того, чтобы оболочка не интерпретировала некоторым специальным образом символы *, ? или пробелы, используются кавычки. Есть ещё много символов, которые надо защищать от интерпретирования. Подробное объяснение этой процедуры даётся в документе Bourne Shell Tutorial (Учебник по оболочке bash), изданном компанией SSC.
Экранная документация укажет также, использует ли команда какие-либо переменные окружения. Например, экранная документация к команде man объясняет, что для назначения программы постраничной выдачи используется переменная PAGER.
Иногда несколько команд используют одну и ту же переменную окружения. Например, многим командам нужна переменная окружения EDITOR, чтобы определить имя редактора, вызываемого (когда требуется) по умолчанию.
Окружение также используется для того, чтобы следить за важной информацией о сеансе работы в системе (login session). Примером может служить переменная окружения HOME, которая содержит имя вашего домашнего каталога (home directory):
/home/larry/papers# echo $HOME /home/larry
Ещё одна интересная переменная окружения — PS1, определяющая вид основного приглашения оболочки. Ей можно присвоить новое значение:
/home/larry# PS1=" Your command, please: " Your command, please:
Для того, чтобы оболочка не трактовала некоторые символы как специальные, часто строки приходится заключать в кавычки. Например, для того, чтобы оболочка не интерпретировала некоторым специальным образом символы *, ? или пробелы, используются кавычки. Есть ещё много символов, которые надо защищать от интерпретирования. Подробное объяснение этой процедуры даётся в экранной документации по bash.
Your command, please: PS1= "\w# " /home/larry#
О синтаксисе, использованном в этой команде, можно прочитать в экранной документации к bash.
Переменная окружения PATH
Допустим вы вводите команду ls. Каким образом, по вашему мнению, оболочка находит исполняемый файл ls? Ответ будет таков: в большинстве случаев исполняемый файл ls находится в каталоге /bin, а командная оболочка использует переменную PATH для поиска исполняемых файлов, соответствующих вводимым командам, и в этой переменной указан нужный путь.
Например, значение переменной PATH может быть таким:
/bin:/usr/bin:/usr/local/bin:.
Это список каталогов, разделённых символом :, в которых командная оболочка будет производить поиск. Когда вводится команда ls, оболочка сначала пытается найти файл /bin/ls, затем — /usr/bin/ls и т. д.
Отметим, что значение переменной PATH влияет только на поиск исполняемых файлов. Например, если вводится команда
/home/larry\# cp foo bar
то оболочка не использует переменную PATH для того, чтобы найти файлы foo и bar — т. е. она считает, что эти имена являются полными. Только при поиске исполняемого файла cp будет использоваться переменная PATH.
Подобная система сохраняет время пользователя и позволяет ему не задумываться о том, где хранятся исполняемые файлы для вводимых им команд. В большинстве систем исполняемые файлы рассеяны по большому количеству каталогов, таких как /usr/bin, /bin, /usr/local/bin. Вместо того, чтобы каждый раз вводить полный путь к исполняемому файлу команды (например, /usr/bin/cp), можно указать список каталогов в переменной PATH, и оболочка будет автоматически просматривать этот список.
Обращаем внимание, что в списке переменной PATH есть ., что обозначает текущий каталог. Это позволяет создавать скрипт или программу и запускать их как команду из текущего каталога, не указывая пути к файлу (например как ./makebook). Если каталог (в том числе и текущий) не находится в списке переменной PATH, то оболочка не будет его просматривать в поиске исполняемого файла.
Скрипты инициализации командных оболочек
Помимо создаваемых вами скриптов командной оболочки, имеется несколько скриптов, которые использует для некоторых целей сама командная оболочка. Наиболее важными из них являются скрипты инициализации (initialization scripts). Эти скрипты исполняются при входе пользователя в систему.
По своей сути скрипты инициализации являются обычными скриптами командной оболочки. Однако они производят инициализацию окружения путём автоматического выполнения некоторых команд; все это происходит при входе в систему. Если, например, при каждом входе в систему вы проверяете, не пришло ли сообщение по почте, вам есть смысл поместить эту команду в скрипт инициализации, так чтобы эта команда исполнялась автоматически.
Как оболочка bash, так и оболочка tcsh делают различия между начальной оболочкой (login shell) и другими ситуациями, когда вызывается оболочка. Начальная оболочка вызывается при входе в систему, и, как правило, это единственная оболочка, с которой вы работаете. Однако когда вы временно выходите (shell out) из некоторой программы, например, из редактора vi, запускается другой сеанс (instance) оболочки, который будет отличаться от сеанса начальной оболочки. Кроме того, новый сеанс оболочки автоматически запускается всякий раз, когда нужно исполнить скрипт.
Инициализационными файлами, используемыми оболочкой bash, являются: /etc/profile (создаётся системным администратором и исполняется всеми пользователями оболочки bash при входе в систему), $HOME/.bash_profile (исполняется при запуске оболочки bash) и $HOME/.bashrc (исполняется остальными сеансами оболочки bash). Если файла .bash_profile нет, вместо него исполняется файл .profile.
Оболочка tcsh использует следующие скрипты инициализации: /etc/csh.login (исполняется всеми пользователями оболочки tcsh при входе в систему), $HOME/.tcshrc (исполняется при входе в систему и при каждом запуске tcsh) и $HOME/.login (исполняется при входе в систему вслед за .tcshrc). Если файла .cshrc.
Создание полного руководства к программированию командных оболочек лежит вне задач данной книги. Более полно о создании индивидуального окружения для работы в системе Linux можно из экранной документации к программам bash и tcsh.