Библиотека сайта rus-linux.net
Оболочка Bourne Again
Свойства
Определения
Инсталляция Bash
Вызов
Синтаксис
Инициализационные файлы
Командная строка и история
Bash - означает Bourne Again Shell и является оболочкой проекта GNU. Она будет оболочкой по умолчанию в операционной системе GNU. Как следует из названия, Bash основывается на оболочке Bourne, sh, созданной Стефеном Борном (Stephen Bourne).
Bash включает в себя свойства оболочек с (csh), tc (tcsh) и Korn (ksh), при этом лишь немногим отличаясь от оболочки Bourne, sh. Так, большинство сценариев sh могут выполняться в оболочке без каких-либо изменений. Различия между bash и sh обусловлены тем, что bash является реализацией спецификации IEEE POSIX 1003.2/ISO 9945.2 Shell and Tools.
Bash была написана Брайаном Фоксом (Brian Fox) (bfox@gnu.ai.mit.edu) из Free Software Foundation, и в настоящее время поддерживается Четом Рэйми (Chet Ramey) из Case Western Reserve University.
Bash распространяется бесплатно, т.е. любой имеет право использовать и распространять ее при определенных условиях, но она не является общественным достоянием. Эта оболочка распространяется в соответствии с лицензией GNU General Public License, копия которой поставляется в распространяемом пакете. Как указывается в лицензии, bash поставляется без каких-либо гарантийных обязательств, поэтому автор и поддерживающий в настоящее время не должны рассматриваться в качестве источников технической поддержки.
На момент написания этой книги последней версией bash была 2.0.0, выпущенная 31 декабря 1996 г., но в настоящее время проходит бета-тестирование версия 2.0.1. Предшественницей версии 2.0.х была версия 1.14.7, выпущенная 28 августа 1996 г.
В этой главе основное внимание уделяется версии 2.0.0, поскольку в ней реализуются некоторые новые свойства, в том числе одномерные множества и встроенная shopt Если не оговаривается иное, все примеры будут выполняться и в среде версии 1.14.7.
Bash доступна посредством анонимного ftp на любом из архивных узлов GNU, в том числе на основном архивном узле GNU, ftp://prep.ai.mit.edu/pub/gnu/bash-2.0.tar.gz. Ее можно также получить с компьютера Чета Рэйми, ftp://slc2.ins.cwru.edu/pub/dist/bash-2.0.tar.gz.
Bash обладает замечательной переносимостью; ее можно скомпилировать из исходников в большинстве систем UNIX, поскольку многие из зависимых от среды переменных определяются во время компиляции. В качестве оболочки Bash может быть перенесена в несколько отличных от UNIX платформ, в том числе QNX, Minix, Windows 95 и Windows NT. Bash является оболочкой по умолчанию для BeOS.
Сборник часто задаваемых вопросов (FAQ) с ответами по Bash можно найти на ftp://slc2.ins.cwru.edu/ pub/bash/FAQ.
Дополнительная информация по bash может быть получена из таких групп новостей Usenet, как gnu.bash.bug и comp.unix.shell.
Свойства
Bash обладает несколькими свойствами, которые делают ее прекрасной оболочкой для использования как новичками, так и экспертами. Многие ее свойства аналогичны свойствам оболочек csh, tcsh и ksh, что облегчает переход с Bash на одну из этих оболочек и обратно.
- Bash обеспечивает редактирование командной строки, аналогичное tcsh и ksh. Курсор может быть перемещен в любую позицию командной строки, что позволяет редактировать команды. Команды редактирования могут быть установлены в режимы vi, emacs или определяемый пользователем.
- Bash также поддерживает механизм истории - повторного вызова и редактирования ранее выполнявшихся команд. Bash может сохранять историю сеанса для использования в других сеансах, в том числе многострочные команды, такие как циклы и функции. Оболочка bash имеет также несколько переменных, влияющих на сохранение и повторный вызов ранее вводившихся команд.
- Оболочка bash обладает свойством завершать частично введенные слова. Оно применимо для имен переменных, пользователей, хостов, команд и файлов.
- Встроенная команда cd оболочки bash может корректировать простые опечатки при вводе путей.
- Оболочка bash допускает функции и псевдонимы. Псевдонимы удобны при выполнении простых задач, например, при создании альтернативного имени команды. Функции обладают расширенными возможностями и удобны при выполнении более сложных задач.
- Bash позволяет приостанавливать и снова запускать процессы, а также осуществлять переключения между задачами переднего плана и фоновые. Bash также имеет команду disown, которая позволяет фоновым задачам продолжать выполнение даже при выходе из родительского процесса.
- Bash 2.0 поддерживает массивы неограниченного размера.
- Bash допускает выполнение арифметических операций с письмами, имеющими основание от 2 до 64, и поддерживает большинство арифметических операторов С. Эта оболочка имеет встроенную поддержку для вычисления численных выражений и подстановки в командной строке и позволяет вводить арифметические выражения в качестве команд.
- Bash обеспечивает специальные последовательности символов, предназначенных для настройки приглашения командной строки. Она допускает использование конструкций других оболочек в приглашении.
Определения
Следующие термины определяются в man-странице BASH(l) и в этом же контексте используются в данной главе:
- пробел Пробел или символ табуляции.
- слово Последовательность символов, воспринимающихся оболочкой как единый блок. (Помимо word, часто используется термин token.)
- имя Слово, состоящее только из алфавитно-цифровых символов и символов подчеркивания и начинающееся с алфавитного символа или символа подчеркивания. Его также называют идентификатором.
- метасимвол Им может быть один из следующих символов: [&;()<> пробел табулятор.
- оператор управления Символ, который выполняет функцию управления. Им может быть один из следующих символов: | & && ; ;; ( ) | <новая_строка>
Инсталляция Bash
Оболочка Bash доступна во многих системах, но для ее инсталляции следует выполнить процедуру, описанную в данном разделе.
Требования
Для установки и инсталляции bash требуются следующие приложения:
- gunzip: для распаковки zip-архива;
- tar: для распаковки tar-архива;
- аг: для построения библиотеки, используемой оболочкой bash;
- gcc или cc: для компиляции bash;
- make: для управления процессом компиляции;
Чтобы убедиться, что эти программы доступны, используйте команду whereis.
Процедура
Получив файл bash-2.0.tar.gz, для построения bash выполните следующую процедуру:
- Выполните команду для перехода в каталог, содержащий tar-файл, упакованный архиватором gzip, bash-2.0.tar.gz.
- Выполните распаковку файла:
gunzip bash-2.0.tar.gz
Файл bash-2.0.tar.gz будет замещен файлом bash-2.0.tar. Чтобы отслеживать работу gunzip, запускайте его с опцией -v.
- Извлеките исходные файлы из bash-2.0.tar:
tar -xvf bash-2.0.tar
При этом создается каталог bash-2.0, в который помещаются исходные файлы.
4. С помощью команды cd выполните переход в каталог с исходными файлами:
cd bash-2.0
5. Сконфигурируйте исходное дерево для своего компьютера:
./configure
Сценарий оболочки configure делает попытку определить правильные значения для зависимых от системы переменных, используемых во время компиляции, а затем создает соответствующий makefile, а также следующие файлы:
config.h - заголовочный файл, содержащий системно-зависимые определения;
config.status - сценарий оболочки, который воссоздает текущую конфигурацию;
config.cache - файл, который сохраняет результаты тестирования для ускорения реконфигурирования;
config.log - файл, содержащий вывод компилятора.
Конфигурация может быть настроена, но для большинства случаев инсталляции конфигурация по умолчанию вполне подходит. Команда конфигурирования имеет опцию справки, которая подробно описывает остальные опции конфигурирования:
./configure -help
Одна из опций конфигурирования определяет каталог, в котором bash должна быть инсталлирована вместо каталога по умолчанию /usr/local:
.configure -prefix=[directory]
В некоторых устаревших версиях System V, если команда configure выполняется из csh, csh может пытаться выполнить configure как сценарий оболочки csh. Во избежания этого следует использовать:
sh .configure
Процесс конфигурирования может занять некоторое время: около 15 минут в Sun Spare 10 и около 10 минут в Sun Ultra 1.
6. Скомпилируйте bash:
По умолчанию команда make будет использовать компилятор gcc, даже если обычный ее инсталлирован и работает. Чтобы использовать ее:
make CC="cc"
make также занимает длительное время: от 20 до 25 минут в Sun Spare 10 и от 15 до 20 минут в Sun Ultra 1.
7. Протестируйте построение (не обязательно, но рекомендуется):
make tests
Тем самым будут созданы и запущены тесты, которые поставляются с исходным кодом для подтверждения надлежащей работы оболочки bash. При выявлении каких-либо проблем bash, по всей видимости, должна быть скомпилирована заново. После завершения тестов имеет смысл вызвать только что скомпилированную оболочку и выполнить несколько команд для подтверждения корректности работы оболочки.
8. Удалите из исполняемой программы отладочные символы (это не обязательно, но рекомендуется):
strip bash
Чтобы увидеть, как влияет команда strip на размеры исполняемого модуля оболочки bash, выполните следующие команды:
ls -l bash ; strip bash ; ls -1 bash
Данная операция уменьшает размер исполняемого модуля примерно на 1 Мб в Sun Spare. Реальное уменьшение размера зависит от используемого компилятора, заданных для него опций, аппаратной платформы и т.п.
9. Инсталлируйте оболочку bash и ее документацию:
make install
В результате bash помещается в каталог по умолчанию, /usr/local. Чтобы посмотреть, что выполняется при инсталляции по умолчанию, не инсталлируя оболочку, выполните команду:
make -n install Для инсталляции bash в каталог, отличный от заранее заданного:
make install prefix=[directory]
Вызов
Оболочка bash может быть вызвана в нескольких различных режимах. Основными являются интерактивный и неинтерактивный режимы.
Интерактивные оболочки
Интерактивная оболочка - это оболочка, стандартный ввод и вывод которой связаны с терминалом. Тремя основными типами интерактивных оболочек являются регистрирующая (login), нерегистрирующая (non-login) и ограниченная (restricted) оболочки.
Bash определяет, является ли оболочка интерактивной, используя вызов библиотеки isatty. В инициализационных файлах и сценариях интерактивные оболочки могут быть определены посредством использования команды tty -s или test -t, которая возвращает 0 (истинно), если стандартным вводом является tty. Интерактивные оболочки устанавливают переменную $PS1, поэтому проверка ее существования - еще один распространенный метод идентификации интерактивных оболочек.
Когда bash вызывается в качестве регистрирующей оболочки, она делает попытку считать несколько Инициализационных файлов и сообщает о всех встретившихся ошибках. Если инициализационные файлы
не существуют, то используется среда, определяемая по умолчанию. Сперва bash считывает и выполняет команды в файле /etc/profile. Затем она проверяет наличие файлов ~/.bash_profile, ~/.bashLogin и ~/.profile и выполняет команды из первого файла. Для предотвращения считывания любых инициализационных файлов оболочке bash может быть передана опция -noprofile. Когда регистрирующая оболочка осуществляет выход, если файл ~/.bashlogout существует, bash будет считывать и выполнять команды из него. Только регистрирующие оболочки будут считывать файл ~/.bashlogout при выходе.
Когда нерегистрирующая интерактивная оболочка запускается, bash считывает и выполняет команды из файла ~/.bashrc. Нерегистрирующую интерактивную оболочку можно заставить считывать различные инициализационные файлы посредством использования опции -rcfile file. Считывание любых инициализационных файлов может быть запрещено посредством опции -nогс.
Посредством опции -posix bash также может быть запущена в режиме posix (Portable Operating System for UNIX). В этом режиме bash сперва проверяет, определена ли переменная $ENV. Если да, то bash читает из $ENV имя файла, а затем считывает и выполняет команды из этого файла. При вызове в режиме posix оболочка bash не будет считывать никакие другие файлы запуска. В этом режиме поведение оболочки несколько изменяется в соответствии со стандартом POSIX.
В некоторых системах, в которых bash называется sh (например, Linux), bash будет запускаться подобно sh, а затем входить в режим posix. Регистрирующая bash, вызванная как sh, будет пытаться считать и выполнить команды в /etc/profile, а затем в ~/.profile. Опция -noprofile предотвратит считывание других инициализационных файлов. Если нерегистрирующая оболочка вызывается как sh, ее поведение при запуске аналогично поведению в режиме posix.
Последний представляющий интерес интерактивный режим - ограниченный режим. Оболочка bash может быть запущена в ограниченном режиме посредством опции -r или вызвана как rbash. В ограниченном режиме bash ведет себя как обычно, за исключением того, что не допускает некоторые операции, такие как смена каталогов, изменение переменных $SHELL или $РАТН, запуск ехес, выполнение команд, содержащих символ / и использование перенаправления. Ограниченный режим недоступен в bash 1-х.
Неинтерактивные оболочки
Неинтерактивные оболочки bash чаще всего используются для выполнения сценариев оболочки. Неинтерактивная оболочка также запускается, когда bash вызывается с опцией -с. Когда неинтерактивная оболочка bash запускается, она ищет переменную среды $BASH_ENV. Если она существует, bash пытается считать и выполнить команды из файла, название которого содержится в этой переменной. Поведение оболочки аналогично поведению при выполнении команды
if [ -n "$BASH_ENV" ] ; then . "$BASH_ENV"; fi
Имя файла, которое определяется переменной $BASH_ENV, не ищется в $РАТН.
Опции вызова
Как отмечалось выше, bash может вызываться с несколькими одно- и многосимвольными опциями. Ниже приводится описание этих опций и выполняемых ими функций:
- -с string Эта опция вызывает считывание команд из строки. Если string содержит более одного слова, первое слово присваивается переменной $0, а *В ~ имя команды и остальные слова - аргументам, т.е. $1, $2 и т.д. Например, bash -с ls /tmp.
- -i Эта опция заставляет оболочку bash запускаться в интерактивном режиме.
- -r Эти опции заставляют bash запускаться в ограниченном режиме.
- --restricted Следующие опции недоступны в bash l.x.
- --login Эта опция заставляет bash вести себя так, как если бы она была регистрирующей оболочкой.
- --posix Эта опция переводит оболочку bash в режим соответствия стандарту POSIX. Эта опция применяется, если bash вызывается с именем sh.
- --verbose Эта опция заставляет оболочку bash отображать все строки ввода после их считывания.
- --help Эта опция заставляет оболочку bash выводить на экран инструкцию по применению оболочки.
- --version Эта опция заставляет оболочку bash выводить информацию о версии. В версиях 2.0 и последующих после вывода информации о версии bash будет успешно завершаться. В версии 1.14.Х и предшествующих выход из оболочки необходимо выполнять вручную.
- --noprofile Эта опция приводит к тому, что интерактивная регистрирующая оболочка bash пропускает считывание инициализационных файлов.
- --nогс Эта опция приводит к тому, что интерактивная нерегистрирующая bash пропускает считывание файла ~/.bashrc.
- --rcfile file Эта опция приводит к тому, что интерактивная нерегистрирующая оболочка считывает команды инициализации из файла file, а не из ~/.bashrc.
Использование bash в качестве регистрирующей оболочки
Наиболее распространенный способ смены регистрирующей оболочки - использование команды смены оболочки chsh. В некоторых системах, в которых chsh недоступна, для смены оболочки может использоваться команда passwd -s или passwd -e. В других системах (в которых используется служба NIS) для смены оболочки должна использоваться команда ypchsh. Во многих системах (например, SunOS 5.5.x) полный путь к исполняемому модулю оболочки bash должен быть включен в файл /etc/shells, прежде чем bash можно будет указать в качестве допустимой регистрирующей оболочки.
Если регистрирующую оболочку, определенную по умолчанию, невозможно заменить, bash все же может быть запущена в качестве регистрирующей оболочки путем использования альтернативных файлов запуска оболочки. Если регистрирующая оболочка по умолчанию --csh или tcsh, a bash размещена в каталоге /usr/ local/bin/bash, то добавление следующей строки в файл ~/.login в начальном каталоге пользователя позволит bash запускаться в качестве регистрирующей оболочки:
if ( -f /usr/local/bin/bash ) exec /usr/local/bin/bash --login
Лучше вызывать bash в файле ~/.login, т.к. он считывается только во время входа в систему в отличие от файла ~/.cshrc, который считывается при каждом запуске csh. Выполнение bash в файле ~/.cshrc может привести к проблемам при попытке запуска сценариев csh. Лучший способ вызова bash в файле ~/.cshrc - запуск ее только в том случае, если csh интерактивна:
if ( $?prompt ) exec /usr/local/bin/bash -login
Если регистрирующей оболочкой является sh или ksh, необходимо выполнить два действия. Во-первых, в файл ~/.profile должна быть вставлена строка, аналогичная следующей:
[ -f /usr/local/bin/bash ] && exec /usr/local/bin/bash -login
Во-вторых, должен быть создан пустой файл ~/.bash_profile, чтобы помешать выполняющейся оболочке bash делать попытки считывания файла ~/.profile и повторного выполнения самой себя. Либо в файл ~/.profile можно было бы вставить следующее:
case "$0" in
*bash)
: "Bash already running";;
*)
[ -f /usr/local/bin/bash ] 6& exec /usr/local/bin/bash -login ;;
esac
При использовании оператора case в файле ~/.profile пустой файл ~/.bash_profile создавать не нужно.
Синтаксис
Bash поддерживает синтаксис, аналогичный синтаксису sh и ksh.
Переменные
Bash 2.0 поддерживает как скалярные переменные, так и массивы. Для установки переменных в bash используется стандартный оператор присваивания оболочки sh:
имя=значение
Переменные-массивы можно определять двумя способами. В первой форме определяется и инициализируется единственный элемент:
имя [индекс] =значение
Вторая форма может использоваться для инициализации нескольких элементов (но не всего массива):
имя=( значение1 ... значение п)
В этой форме используются последовательные индексы, начиная с 0. Например, оператор myarray=(derri terry mike gene) эквивалентен операторам
myarray[0]=derri
myarray[1]=terri
myarray[2]=mike
myarray[3]=gene
При установке нескольких элементов массива, индекс массива может быть помещен перед значением, этому третий способ инициализации элементов массива будет выглядеть так:
myarray=([0]=derri [3]-gene [2]=mike [1]=terri)
He существует ограничений ни на максимальное значение индексов массива, ни на последовательность использования.
Bash также поддерживает две встроенные команды declare и typeset, которые обеспечивают изменение атрибутов переменных. Эти две команды являются синонимами и допускают определение переменных как массивов, переменных целого типа и переменных только для чтения, а также позволяют помечать переменные для экспорта. Следует использовать команду declare, поскольку в настоящее время команда typeset является устаревшей.
При использовании в арифметических выражениях, переменная помеченная как целая, ведет себя аналогично переменным типа hit языка программирования С. Переменные только для чтения, будучи присвоены, не могут быть присвоены повторно; фактически, это константы. Команды declare и typeset воспринимают следующие опции:
- ф
- -а Устанавливает/отменяет установку атрибута массива для переменной declare -a foo t теперь foo является массивом
- [-/+] i Устанавливает/отменяет установку атрибута целого типа для переменной
declare -i foo # переменная foo будет обрабатываться как переменная целого типа
declare +i bar # переменная bar будет обрабатываться обычным образом
- [-/+] г Устанавливает для переменной атрибут только для чтения.
declare -r foo # значение переменной foo не может быть изменено
- [-/+] х Устанавливает/отменяет установку атрибута экспорта для переменной declare -х foo # переменная foo помечена для экспорта declare -х foo # переменная foo не будет экспортироваться
-р variable Показывает атрибуты переменной variable. Если переменная не указана, отображаются все переменные и их значения. Эта опция недоступна в bash l.x.
Экспорт переменных для использования в среде оболочки аналогичен экспорту в sh. Для пользователей csh и tcsh это аналогично созданию переменных среды с помощью команды setenv. Пометка переменной i экспорта означает, что она доступна для использования в среде дочернего процесса оболочки. Экспорт может быть выполнен двумя способами:
export name
export name=value
Первая форма помечает именованную переменную для экспорта. Вторая форма присваивает именованной переменной заданное значение, а затем помечает эту переменную для экспорта. Может быть указано болee одного имени пате или пар name-lvalue. Переменные могут быть неэкспортируемыми, если указана опция -n. Ели экспорт вызывается самостоятельно или с опцией -р, будет выводиться список экспортированных переменных. Оба следующих примера представляют допустимый способ экспорта переменной PATH:
PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/ucb
export PATH
export PATH=/bin:/sbin:/usr/bin:/usr/local/bin:/usr/ucb
В дополнение к этим атрибутам bash позволяет посредством использования встроенной команды local печать переменные как локальные. Это означает, что отдельный экземпляр переменной создается для функции, в которой используется команда local (эта команда может использоваться только в функциях). Существуют две формы команды:
local name
local name=value
Первая форма создает переменную с данным именем и помечает ее как локальную. Вторая создает песенную с заданным именем и заданным значением. Если команда local вызывается без параметра name или name=value, она будет выводить список существующих в данный момент локальных переменных. Во время запуска bash автоматически инициализирует несколько переменных, некоторые из которых 1адают специальными свойствами до тех пор, пока их установка не отменена. Ниже приводится сокращенный перечень этих переменных оболочки:
- $PWD Текущий рабочий каталог, установленный командой cd.
- $UID Этой переменной присваивается значение цифрового идентификатора текущего пользователя; она инициализируется при запуске оболочки.
- $BASH Содержит полный путь, используемый для вызова данного экземпляра оболочки bash.
- $BASH_VERSION Содержит строку, описывающую версию данного экземпляра оболочки bash.
- $BASH_VERSINFO Переменная массива, члены которого содержат информацию о версии данного экземпляра оболочки bash.
- $SHLVL Значение этой переменной увеличивается на единицу при каждом запуске экземпляра оболочки bash. Эта переменная удобна для определения того, когда встроенная команда exit завершит текущий сеанс.
- REPLY Содержит последнюю строку ввода, считанную встроенной командой read, когда ей не передаются никакие аргументы.
- $RANDOM Эта переменная содержит случайное число в диапазоне от 0 до 32767, которое генерируется при каждом очередном обращении к ней. Генератор случайных чисел может быть инициализирован посредством присвоения значения переменной $RANDOM. Если при запуске этой переменной не присваивается значение, она утрачивает свои специальные свойства, даже если впоследствии она инициализируется.
- $SECONDS При каждом обращении к этому параметру возвращается значение времени в секундах, прошедшего с момента вызова оболочки. Если переменной $SECONDS присвоено значение, при последующих обращениях к ней возвращается значение времени в секундах, прошедшего с момента присвоения, плюс присвоенное значение. Если инициализация $SECONDS при запуске оболочки отменена, переменная утрачивает свои специальные свойства, даже если впоследствии она инициализируется снова.
- $HISTCMD Номер текущей команды в перечне ранее выполнявшихся команд или индекс в списке истории. Если инициализация $HISTCMD при запуске отменена, переменная утрачивает свои специальные свойства, даже если впоследствии она инициализируется снова.
- $IFS Internal Field Separator (Внутренний разделитель полей), который используется программой синтаксического анализа для разделения слов после раскрытия. $IFS также используется для разбиения строк на слова встроенной командой read. Значением по умолчанию является
<space><tabXnewline>
Следующие переменные используются оболочкой bash, но первоначально инициализируются другими программами:
- $РАТН Путь поиска команд. Представляет собой разделенный двоеточиями список каталогов, в которых оболочка ищет команды. Обычным значением является PATH=/bin:/sbin:/usr/bin:/usr/local/bin:sr/ucb
- $HOME Начальный каталог текущего пользователя; аргумент по умолчанию для встроенной команды cd.
Кроме этих типов переменных, bash поддерживает также два дополнительных типа параметров: позиционный и специальный. Значения обоих этих параметров присваиваются оболочкой bash, но только значения позиционных параметров могут изменяться.
Позиционные параметры обозначаются одной или несколькими цифрами, начиная с 1; доступ к ним можно получать индивидуально, передавая номер аргумента в качестве имени переменной. Если номер аргумента состоит из нескольких цифр, необходимо использовать фигурные скобки. Например, доступ к первому аргументу можно получить посредством $1, но для одиннадцатого аргумента необходимо использовать ${11}.
Существует несколько специальных параметров, связанных с позиционными параметрами:
- $* Раскрывает единственное слово, содержащее список всех позиционных параметров, разделенных первым символом $IFS (обычно пробелом).
- $@ Этот позиционный параметр замещается последовательностью слов, а не одним словом, как $*.
- $# Этот параметр содержит число позиционных параметров.
Позиционные параметры - это аргументы, с которыми вызывается функция или сценарий оболочки. означает, что значение $1 различно внутри и снаружи функции.
Остальные специальные параметры связаны с выполнением команд и освещаются в разделе "Переменные истории".
Инициализация как переменных, так и массивов, может быть отменена с помощью команды unset:
unset name
unset -v name
Опция -v во второй форме используется для указания команде unset того, что имя является переменной оболочки. Эта опция необязательна.
Интерпретация и подстановка значений
Когда bash встречает оператор присваивания в форме:
name=value
значение value присваивается переменной name после выполнения интерпретации символов тильды, переменных и строк. Перед присваиванием значения оболочка bash будет также выполнять подстановку команд, арифметические вычисления и удаление кавычек.
Интерпретация тильды выполняется, когда тильда (~) является первым символом в слове. В этом случае bash обрабатывает символы, следующие за тильдой, как регистрационное имя пользователя и пытается выполнить подстановку начального каталога, связанного с ними. Если тильда появляется самостоятельно или за ней следует косая черта (/), а переменная $НОМЕ установлена, bash подставляет вместо тильды значение переменной $НОМЕ. В противном случае она замещает тильду начальным каталогом текущего пользователя. Если вводится ^+, bash замещает их значением переменной $PWD, т.е. текущим каталогом. Символы ~- замещаются значением переменной $OLDPWD - предшествующим рабочим каталогом. Если ни одним из этих способов раскрытый тильду невозможно интерпретировать, bash оставляет тильду без изменений.
Оболочка bash выполняет подстановку значения переменной, когда встречает символ $. Простейшими формами являются
foo=$bar
foo=${bar}
В этих примерах значение переменной $bаг присваивается переменной $foo. Во второй форме фигурные скобки используются для явного указания программе синтаксического анализа, где заканчивается имя переменной. Например,
foo=24
echo $footh
осуществляет вывод значения переменной $footh, в то время как
foo=24
echo ${foo}th
выполняет вывод строки 24th, которая является значением переменной foo с добавленными символами "th". Подстановка значений переменных может также выполняться несколькими более сложными способами:
- Если $bаr не инициализирована или равна нулю, и необходимо генерировать ошибку: ${bar:?"Error, no bar"}
- Если $bаr не инициализирована или равна нулю, но должна иметь значение по умолчанию: ${bar:="foose"}
- Если $bаr не инициализирована или равна нулю, но $foo должна иметь значение: fоо=${bаr:-''гоозе''}
- Если $foo должна иметь значение, когда $bаr не инициализирована или равна нулю: foo=${bar:+"foose"}
Оболочка bash поддерживает также подстановку подстрок переменных, что может использоваться для присвоения частей значения одной переменной другой:
foo=${bar:offset:length}
offset - начальная позиция в $bar, a length - количество символов, подлежащих получению. Если длина length не указана, возвращаются все символы, следующие за offset. Подстановка команды выполняется, когда команда вводится в виде
$(command)
'command'
Обе формы замещаются выводом команды. Если только команда не заключается в двойные кавычки, каждая строка вывода команды становится отдельным словом. В случае наличия двойных кавычек, вывод обрабатывается как единое слово, содержащее символы новых строк.
Арифметическое вычисление выполняется, когда встречается следующая конструкция:
$((expression))
выражение будет вычисляться в соответствии с правилами языка программирования С, и результат будет подставлен. Например,
foo=$(( ((5 + 3*2) - 4) / 2))
переменная foo получит значение, равное 3 (а не 3.5, т.к. данное число является целым).
Удаление кавычек выполняется после того, как выполнены все остальные подстановки, при этом удаляются все остающиеся символы, не связанные с кавычками: \ (обратная косая черта), ' (одиночная кавычка) и " (двойная кавычка).
Bash выполняет еще два типа интерпретации - интерпретацию фигурных скобок и путей. Это применяется прежде всего к командам, вводимых в командной строке. Фигурные скобки в основном используются для создания нескольких строк, имеющих общие элементы. Общей формой является
stringx{stringl, string2, ... , stringn)stringy
Оболочка bash раскрывает эту строку в строки, ограниченные квадратными скобками [], каждая из которых содержит одну из строк, перечисленных в фигурных скобках, имеющую префикс stringx и суффикс stringy. Строка префикса или ведущая строка может быть опущена, но минимальное количество строк в фигурных скобках, { }, равно одной, а элементы в фигурных скобках должны разделяться запятыми. Фигурные скобки в данном контексте могут применяться в ситуациях, подобных следующим:
mkdir /home/ranga/docs/{school,work,personal}/mail
mkdir -p /usr/local/{bin,lib,man/nian{l,2,3},etc}
Эти строки эквивалентны
mkdir /home/ranga/docs/school/mail/home/ranga/docs/work/mail/home/ranga/docs/personal/mail
mkdir -p /usr/local/bin/usr/local/lib/usr/local/man/manl/usr/local/man/man2/usr/local/man/man3/ usr/local/man/etc
Интерпретация фигурных скобок может применяться в сочетании с интерпретацией пути, что позволяет вставлять в пути некоторые специальные символы. Если эти символы вставлены, слово, в котором они присутствуют, считается шаблоном и замещается упорядоченным списком имен файлов, соответствующих шаблону. Специальными символами являются:
- * Соответствует любой строке, в том числе нулевой.
- ? Соответствует любому одиночному символу.
- [...] Соответствует любому из символов, заключенных в скобки. Пара символов, разделенных знаком минуса, обозначают диапазон, и любой из символов, попадающий в этот интервал, соответствует шаблону. Например, [A-Z] соответствует всем прописным буквам, a [a-z,A-Z] соответствует всем буквам.
Кавычки
Кавычки используются для отмены значения определенных символов, которые оболочка обрабатывает специальным образом. Кавычки могут использоваться для создания строк путем помещения ряда символов в одиночные О или двойные (") кавычки. Например, следующие строки образованы с помощью кавычек:
"Hello, I am a string"
So I am'
Одиночный символ также может быть помещен в кавычки, если ему предшествует обратная наклонная черта (\). Кроме того, кавычками отменяются значения следующих символов:
`~!#$%^&*()-+=\|;':,.<>?
Использование кавычек в bash объединяет правила использования кавычек, имеющиеся в sh и csh. Значения всех специальных символов в строках, заключенных в одиночные кавычки, 'string', отменяются. В строках, заключенных в двойные кавычки, "string", отменяются значения всех специальных символов, за исключением !, $, \ \ и {. Обратная наклонная черта (\) отменяет специальное значение символов.
Кроме кавычек, bash распознает несколько стандартных escape-последовательностей, знакомых программистам -работающим на языке С, например \t для символа табуляции и \n для символа новой строки.
Простые команды
Простыми командами в bash являются присваивания значений переменным, имена отдельных команд или имена отдельных команд, вывод которых перенаправляется. Bash обрабатывает первое слово командной строки в качестве команды, подлежащей выполнению, а остальные слова - в качестве аргументов команды, если только команде не предшествуют присвоения переменных. Простая команда будет возвращать свое состояние выхода или 128+SIG, если она прерывается сигналом с номером SIG.
Конвейеры
Несколько простых команд могут быть объединены с помощью символов каналов, образуя конвейер. commandl | command2 | ...
Символ канала | соединяет стандартный вывод команды command 1 со стандартным вводом команды command2 и т.д. Каждая команда выполняется в качестве отдельного процесса. Состояние выхода конвейера - это состояние выхода последней команды. Примерами конвейерных команд могут служить
tail -f /var/adm/messages | more
ps -ael | grep "$1110" ! more
tar -cf - ./too | { cd /tmp; tar -xf - }
В первом примере стандартный вывод команды tail передается стандартному вводу команды more, что позволяет просматривать вывод поэкранно. Во втором примере стандартный вывод команды ps соединяется со стандартным вводом команды grep, а стандартный вывод команды grep соединяется со стандартным вводом команды more, чтобы вывод команды grep можно было просматривать поэкранно. Третий пример ~ сложный, но иногда полезный для привилегированного пользователя, способ копировать файлы, не меняя их владельца.
Списки
Кроме конвейеров, команды могут выполняться в списках, когда несколько конвейеров объединятся с помощью операций ;, &, && или ||. Список может использоваться для последовательного выполнения команд и конвейеров:
commandl; command2; command3 ...
commandl | command2; commands | command4 ...
Обычно списки используются для таких задач, как
lpr foo; lpq;
ps -ael | head -1; ps -ael | grep "$UID"
которые не могут быть выполнены в одной команде.
Списки могут также использоваться для выполнения команд, основывающихся на состоянии выхода предыдущих команд, если применяются операции логического AND (И) или OR (ИЛИ):
commandl && command2
commandl || command2
Если используется операция логического AND, как в первом случае, команда command2 будет выполняться только если команда commandl возвратит состояние выхода равное 0. При использовании операции логического OR, как во втором случае, команда command2 будет выполняться только если команда commandl возвратит ненулевое состояние выхода. Логические операции часто используются вместо операторов if; эта форма должна казаться очевидной тем пользователям, которые знакомы с языком программирования С и его "ленивыми" логическими операторами.
Операция && обычно используется в ситуациях, подобных
mkdir foo && cd foo
где смена каталога может быть выполнена, только если каталог был успешно создан. А вот пример использования операции ||:
grep root /etc/passwd || echo "Help! No one in charge!"
Любой список может выполняться в среде текущей оболочки или в субоболочке. Заключение списка в фигурные скобки
( list ; }
приводит к тому, что список будет выполняться в текущей оболочке, а заключение его в круглые скобки
( list ; )_
приводит к выполнению списка в субоболочке. Например, команда
{ ps -ael [ head -1; ps -aei I grep " $UID " ; } | more
выполняет список ps -ael | head -1; ps -ael | grep " $UID" в текущей оболочке, а затем передает вывод команде more. Этот же список можно было бы выполнить в субоболочке:
( ps -ael | head -1; ps -ael I grep " $UID " ; ) | more
но это, вероятно, не слишком удачная мысль, поскольку каждая выполняющаяся субоболочка занимает дополнительные системные ресурсы. Эффективней было бы выполнять все программы в текущей оболочке. Выполнение списков в субоболочках удобно, т.к. субоболочки, по-существу, делают все переменные локальными, а также потому, что субоболочки имеют собственные рабочие каталоги. Это иллюстрируется следующим примером:
pwd; ( cd /tmp ; pwd ) ; pwd;
Текущий рабочий каталог меняется только для субоболочки.
Перенаправление
Списки могут также содержать перенаправление ввода и вывода с использованием операций < и >. По умолчанию операция < перенаправляет стандартный ввод, а операция > - стандартный вывод, но операции перенаправления могут также использоваться для открытия и закрытия файлов. В общем случае перенаправление вывода имеет вид
command > file
ИЛИ
List > file
Первая форма перенаправляет вывод команды command в файл file, а вторая перенаправляет вывод списка list в файл file. Например,
date > now
перенаправляет вывод команды date в файл now. Вывод списка также может быть перенаправлен.
{ date; uptime; who ; } > mylog
перенаправит вывод всех команд date, uptime и who в файл mylog. Кроме такого перенаправления вывода, который переписывает файл вывода, существует добавляющее перенаправление вывода. Вывод будет добавляться к файлу, или файл будет создаваться, если он не существует, при использовании операции р. В общем случае добавляющее перенаправление вывода выглядит следующим образом:
command >>file
list >> file
Чтобы файл mylog (в ранее приведенном примере) не удалялся при каждом добавлении данных, можно использовать следующее:
{ date; uptime; who ; } >> mylog
Оболочка bash допускает также, чтобы стандартный вывод и стандартный вывод ошибок перенаправлялись в один файл. В общем случае это делается следующим образом:
&> file >& file
> file 2>&1
Как утверждается в руководствах, первая форма предпочтительней, но все три являются эквивалентными. Третья форма работает посредством использования дескрипторов файлов стандартного вывода (дескриптор файла равен 1) и стандартных ошибок (дескриптор файла равен 2); по существу, она делает то же, что библиотечная функция dup2() языка С. Распространенная ситуация, когда требуется перенаправлять и стандартный вывод и стандартную ошибку, следующая
if type emacs &> /dev/null ; then
EDITOR=emacs
else
EDITOR=vi
fi
В данном случае только возвращаемое значение встроенной команды type представляет интерес, а ее вывод или любые сообщения об ошибках - нет, поэтому они перенаправляются в файл /dev/null.
Ввод также может быть перенаправлен аналогичным образом. В общем виде перенаправление ввода следующее:
command < file
В этом случае содержимое файла file станет вводом команды command. Например, следующая строка является обычным использованием перенаправления:
Mail ranga@soda.berkeley.edu < Final_Exam_Answers
где вводом команды Mail, который становится телом почтового сообщения, будет файл Final_Exam_Answers. Перенаправления ввода находит дополнительное применение при создании документов Here, Общая форма документа Here следующая
command << delimiter
document
delimiter
Оболочка будет интерпретировать операцию р как инструкцию на считывание ввода до тех пор, пока не будет найдена строка," содержащая указанный ограничитель delimiter. Все строки ввода, включая строку, содержащую delimiter, передаются стандартному вводу команды command. Оболочка bash не выполняет никакой интерпретации данного ограничителя delimiter, но читает строки в документе Here. Например, для печати краткого списка URL можно было бы использовать следующий документ Here:
lpr << MYURLS
http: //www. csua.berkeley.edu/-"ranga/
http://www.macintouch.corn/
http://www.marathon.org/story/
http://www.gnu.org/
MYURLS
Это обеспечивает удобную альтернативу созданию временных файлов. Для удаления символов табуляции в этом примере операции р может быть придана опция -.
Управление потоками
Оболочка bash обеспечивает два мощных механизма управления потоками: конструкции if-fi и case-esac. Оператор if обычно используется для условного выполнения команд, а оператор case обеспечивает выполнение любого числа последовательностей команд в зависимости от того, какой из нескольких шаблонов первым оказывается соответствующим указанной переменной. Часто проще создавать операторы if, чем операторы case, если в них используется соответствие переменной шаблону.
Общий синтаксис оператора if следующий: if list; then list; lelif list; then list; ] ... [else list;] fi, что обычно записывается как:
if list ; then
list2
elif list3 ; then
list4
else
list5
fi
Операторы elif и else являются необязательными. Оператор if может содержать любое число операторов elif и может иметь только операторы if и elif. Списками в операторах if могут быть списки, описанные в предыдущем разделе.
В общем случае при интерпретации оператора if сперва вычисляется listl. Если код выхода списка listi равен 0, указывая на истинность условия, вычисляется list2 и оператор if осуществляет выход. В противном случае выполняется list3, а затем его код проверяется. Если list3 возвращает 0, то выполняется list4 и оператор if осуществляет выход. Если list3 возвращает ненулевое значение, выполняется list5. Простой пример использования оператора if показан ниже:
if uuencode koala.gif koala.gif > koala.uu ; then
echo "Encoded koala.gif to koala.uu"
else
echo "Error encoding koala.gif"
fi
Строка "Encoded koala.gif to koala.uu" будет выводиться, если код выхода команды uuencode указывает на успешное выполнение. В противном случае будет выводиться сообщение об ошибке.
Чаще всего список list, включенный в оператор if, будет одной или несколькими командами test, которые могут вызываться в виде test expression или [expression]. После вычисления выражения expression команда test возвращает 0 (истинно) или 1 (ложно). Ниже приводится перечень наиболее часто используемых при выполнении команды test опций:
- -d file Истинно, если файл file существует и является каталогом.
- -е file Истинно, если файл file существует.
- -f file Истинно, если файл file существует и является обычным файлом.
- -k file Истинно, если файл file существует и для него установлен "клейкий" бит.
- -L file Истинно, если файл file существует и является символической ссылкой.
- -г file Истинно, если файл file существует и может быть считан.
- -s file Истинно, если файл file существует и имеет размер больше нулевого.
- -t file Истинно, если file открыт на терминале.
- -w file Истинно, если файл file существует и в него можно записывать.
- -х file Истинно, если файл file существует и является исполняемым.
- -О file Истинно, если файл file существует и принадлежит текущему пользователю
- filel -nt file2 Истинно, если файл filel создан (изменен) позднее, чем файл file2.
- filel -ot file2 Истинно, если файл filel создан (изменен) раньше, чем файл file2.
- -z string Истинно, если длина строки string равна нулю.
- -n string Истинно, если длина строки string не равна нулю.
- string 1 = string2 Истинно, если строки равны.
- string1 == string2 Истинно, если строки равны.
- string1 != string2 Истинно, если строки не равны.
- ! ехрr Истинно, если выражение ехрr ложно. Выражением ехрr может быть любое из вышеприведенных.
- ехрr1 -а ехрr2 Истинно, если оба выражения ехрr! И ехрr2 истинны.
- ехрr1 -о ехрr2 Истинно, если любое из выражений ехрr1 ИЛИ ехрr2 истинно.
- arg1 OP arg2 OP - это одна из операций -eq, -nе, -lt, -le, -gt или -ge. Эти двоичные арифметические операции возвращают значение истинности, если arg! равен, не равен, меньше, меньше или равен, больше, или больше или равен arg2, соответственно. Аргументами arg! и arg2 могут быть положительные или отрицательные целые значения.
Примерами использования простого оператора if в сочетании с проверкой условий являются
if [ -d $HOME/bin ] ; then PATH="$PATH: $HOME/bin"; fi
if [ -s $HOME/.bash_aliai ] ; then . $HOME/bash_aliai ; fi
В первом примере проверка условия используется для определения того, существует ли каталог, после чего выполняется некоторое действие.
Во втором примере проверка используется для определения того, существует ли файл, имеющий ненулевой размер, перед выполнением любого действия.
Ниже приводятся еще два эквивалентные примера, демонстрирующие объединение проверок:
if [ -z "$DTHOME" ] && [ -d /usr/dt ] ; then DTHOME=/usr/dt ; fi
if [ -z "$DTHOME" -a -d /usr/dt ] ; then DTHOME=/usr/dt ; fi
Некоторые пользователи предпочитают первую форму, поскольку в ней более очевидно, какие проверки подлежат выполнению и каковы критерии вычисления. Другие предпочитают вторую форму, т.к. в ней команда [ используется только один раз и она может быть более эффективной.
Вторая форма управления потоками - конструкция case-esac. Общий синтаксис выглядит следующим образом: case word in [ pattern [ | pattern ] ... ) list ;; ] рesac, но обычно это записывается как
case word in pattern) list ;;
pattern2)
list2
;;
esac
в этой форме word - это либо строка, либо переменная, значение которой сравнивается с каждым шаблоном pattern, пока соответствие не будет найдено. Список list, следующий за совпадающим шаблоном, выполняется. Как только список выполнен, поток выполнения программы переключается на конец оператора case. Если ни одно совпадение не обнаружено, оболочка bash выполнит выход из оператора case. Некоторые действия по умолчанию могут выполняться посредством использования шаблона *, соответствующего любым значениям. Количество шаблонов не имеет значения, но должен существовать по меньшей мере один. Шаблоны могут использовать те же специальные символы, что и шаблоны для расширений путей, которые могут объединяться операцией OR (или), |. Символы ;; показывают оболочке bash, что список исчерпан, и аналогичны break в языке С. Ниже приведен пример простого оператора case
case "$TERM" in
*term)
TERM=xterm ;;
network|dialup\unknown\vt[0-9]*)
TERM=vtlOO ;;
esac
Циклы
Bash поддерживает три типа циклов: for, while и select. Цикл for используется, когда набор команд нужно просто выполнять повторно. Цикл while используется, когда набор команд должен выполняться до тех пор, пока определенное условие истинно. Общепринятое использование цикла select - обеспечение удобного интерфейса выбора.
Общий синтаксис цикла for следующий: for name [ in listi; ] do list2 ; done, но обычно это записывают как
for name in list1
do
list2
done
В цикле for имя переменной устанавливается равным каждому элементу списка listi, а список list2 выполняется для каждого элемента списка listi. Если список не приводится, bash будет просматривать позиционные параметры. Если listi приведен в качестве слова, будет выполнена его интерпретация. Простой пример цикла for выглядит следующим образом:
for i in 123456789 10 do
echo $i done
Более распространенное применение цикла for показано ниже:
for files in -/.bash_*
do
echo "<HTML>" > ${files}.html
echo "<HEAD><TITLE>$files</TITLE></HEAD>" >> ${files} .html
echo "<BODY><PRE>" >> ${files}.html
cat $files >> ${files}.html
echo "</PRE><BODY>">> ${ files} .html
echo "</HTML>" >> ${files}.html
chmod guo+r ${files}.html
done
Цикл while имеет следующий общий синтаксис: while list1 ; do list2 ; done. Обычно это записывают как
while list1
do
list2 done
В цикле while список list1 вычисляется каждый раз, и пока его значение истинно, список list2 выполняется. Это позволяет писать бесконечные циклы, имеющие /bin/true в качестве списка list1. Ниже приведен простой пример цикла while.
X=1
while [ $x -It 10 ]
do
echo $x x=$(($x+l))
done
Этот цикл while копирует свой вывод во ввод, подобно программе cat:
while read
do
echo $REPLY;
done
Если используется перенаправление ввода, этот цикл запишет содержимое файла ввода в стандартный вывод, подобно программе cat.
Вариантом цикла while является цикл until:
until list1
do
list2 done
В цикле until список list2 выполняется до тех пор, пока список list1 не становится истинным. Цикл until аналогичен циклу while в котором указано ! list1. Следующие циклы while и until эквивалентны:
x=1; while ! [ $х -де 10 ] do
echo $x
х=$(($х+1))
done
x=l; until [ $x -де 10 ] do
echo $x
x=$(($x+l)) done
Цикл select служит простым способом создания пронумерованных меню, из которых пользователи могут выбирать опции. Общий синтаксис цикла select выглядит как select name [ in list1; ] do list2 ; done и обычно записывается
select name in list1
do
list2 done
В цикле select элементы в списке list1 выводятся в стандартную строку ошибки с номером в качестве префикса. Затем отображается приглашение и строка считывается. Если переменная $REPLY, содержащая значение считываемой строки, содержит номер отображаемого пункта, список list2 выполняется. В противном случае элементы списка list1 последовательно отображаются снова. Цикл select завершается, если считывается EOF (end of file - конец файла).
Следующий цикл select отображает нумерованный список файлов, находящихся в каталоге /tmp, и выполняет команду ls -1 по отношению к существующим файлам:
select file in /tmp/* QUIT
do
if [ -e $file ] ; then
Is -1 $file else
break
fi
done
Вывод будет аналогичен следующему:
1) /tmp/. 6) /tmp/job.control.ms
2) /tmp/.. 7) /tmp/job.control.ps
3) /tmp/.Xll-unix 8) /tmp/ps_data
4) /tmp/intro7.html 9) /tmp/sunpro.с.1.157.3.00
5) /tmp/java 10) QUIT #?
Где #? ~ приглашение, по которому пользователь вводит номер.
Все циклы в оболочке bash могут осуществлять немедленный выход, используя встроенную команду Weak. Эта команда также воспринимает в качестве аргумента целое значение, большее или равное 1, которое показывает число уровней вложенности, для которых требуется выполнить прерывание цикла. Это свойство удобно при использовании вложенных циклов.
Комментарии
Комментарии оболочки bash начинаются с символа #. Все символы между # и символом новой строки считаются частью комментария и игнорируются оболочкой. По умолчанию это справедливо как для интерактивных, так и не интерактивных оболочек. Интерактивные оболочки могут изменять это поведение, .используя встроенную функцию shopt.
Инициализационные файлы
Интерактивная регистрирующая оболочка bash считывает файлы ~/.bash_profile, ~/.bash_login и ~/.profile, а нерегистрирующая оболочка bash будет считывать файл ~/.bashrc. Число инициализационных файлов, которые bash должна считывать при запуске, приводят в растерянность многих пользователей.
Соображения по поводу инициализационного файла
Одна из основных проблем, встающая перед пользователем, который только начинает знакомиться с bash, - это какие инициализационные файлы создавать и что помещать в них. Простейшее решение, выработанное множеством пользователей bash, состоит в создании одного инициализационного файла, а остальные инициализационные файлы являются символическими ссылками на этот файл.
Большинство пользователей создают файл ~/bash_profile и делают файл ~/.bashrc ссылкой на ~/.bash_profiie, что обеспечивает одну и ту же среду для регистрирующих и нерегистрирующих интерактивных оболочек bash. Файл ~/.bash_profile больше подходит в качестве инициализационного, чем файл ~/.bash_login, поскольку именно его оболочка bash пытается считать первым.
Некоторые пользователи bash, применяющие sh и ksh вместе с bash, используют только файл ~/.profile и включают в него специальный раздел для bash, используя проверку условий, подобную следующей:
if [ -n "$BASH" ] ; then . . . (Bash specific code here) ... ; fi
В этом случае файл ~/.bashrc будет символической ссылкой на файл ~/.profile. Если bash будет единственной используемой sh-подобной оболочкой, вероятно, лучше создать ~/.bash_profile, поскольку при этом можно избежать проблем совместимости, появляющихся в связи с использованием файла ~/.profile.
В наиболее общем случае инициализационные файлы должны устанавливать маску создания файлов и переменную $PATH, содержащую путь поиска команд, поскольку они используются и интерактивными и неинтерактивными оболочками. Большинство инициализационных файлов содержит, помимо этого, множество переменных и опций, применяемых только для интерактивных оболочек. Вот некоторые действия, которые обычно выполняются в инициализационных файлах для интерактивных оболочек:
- проверка того, что терминал установлен надлежащим образом;
- инициализация переменной $MANPATH, содержащей путь поиска man-страниц;
- инициализация переменной $LD_LIBRARY_PATH, содержащей путь поиска библиотек;
- инициализация переменных $PS1 и $PS2, определяющих первичное и вторичное приглашения.
Некоторые пользователи также определяют в инициализационных файлах псевдонимы и функции, но большинство предпочитает определять их в другом файле, называемом .bash_aliases или .bash_aliai. Одна из причин этого - желание избежать модификации инициализационного файла при каждом добавлении псевдонимов или функций. Поскольку использование файла, содержащего псевдонимы, не представляет сложности, использование дополнительного файла не усложняет инициализационный файл.
Переменные оболочки
Этот раздел содержит перечень некоторых переменных, используемых оболочкой bash, значения которых задаются в инициализационных файлах. В следующем примере показано, как задаются значения переменных в инициализационном файле.
Ниже приведен перечень переменных, являющихся списками имен каталогов, разделяемых двоеточиями (:), которые используются при поиске файлов:
- $PATH Путь поиска для команд, обычно подобный PATH=/bin:/usr/bm:/usr/local/ bin:usr/ucb/
- $MANPATH Путь поиска man-страниц, чаще всего что-либо, аналогичное /usr/man:/usr/ local/man
- $LD_LIBRARY_PATH Путь поиска библиотек, обычно что-либо наподобие /)ib:/usr/lib:/usr/local/ lib:/usr/ucbinclude:/usr/ucblib
- $CD_PATH Путь поиска каталогов для команд cd, обычно подобный .:~:~/docs
Следующие переменные относятся к редактору, используемому по умолчанию, и обычно являются именем команды редактора, включая опции, используемые при его запуске:
- $EDITOR Имя строчного редактора по умолчанию (ed)
- $VISUAL Имя визуального редактора по умолчанию (vi)
- $FCEDIT Имя редактора для использования с встроенной командой fc Следующие переменные оболочка bash использует при проверке почты:
- $MAIL Файл, в котором хранится почта пользователя, и файл, в котором оболочка bash будет искать почту. Обычно предварительно устанавливается значение, подобное /usr/spool/inail/ranga.
- $MAILCHECK Значение этой переменной - время в секундах между проверками почты. По умолчанию устанавливается 60. Если эта переменная не инициализирована, bash не будет проверять почту.
- $MAIL_PATH Список файлов, разделенных двоеточием (:), в которых необходимо искать почту.
Следующие переменные управляют тем, как и где bash помещает команды в перечне ранее вводившихся команд.
- $HISTSIZE Значение этой переменной - число команд, которые необходимо запоминать в истории. Значение по умолчанию - 500.
- $HISTFILE Эта переменная содержит имя файла, в котором сохраняется история. По умолчанию это ~/.bash_history.
- $HISTFILESIZE Значение этой переменной ~ максимальное число строк, подлежащих включению в файл истории. По умолчанию оно равно 500.
- $HISTCONTROL Эта переменная может иметь три специальные значения: ignorespace, ignoredups и ignoreboth. Другие значения не оказывают никакого влияния. Если установлено значение ignorespace, то команды, начинающиеся с пробелов, не запоминаются историей. При установке ignoredups последовательные идентичные команды не запоминаются в файле истории. Установка значения переменной равным ignoreboth объединяет две предыдущие опции.
Оболочка bash использует также следующие переменные:
- $TERM Тип терминала (например, xterm, vtlOO).
- $PAGER Имя утилиты постраничного просмотра, используемой по умолчанию (например, less, more).
- $PRINTER Имя принтера, используемого по умолчанию.
- $IGNOREEOF Значение этой переменной - число символов EOF, которые могут быть получены в качестве единого ввода, прежде чем bash осуществит выход. Значение по умолчанию - 10.
- $TMOUT ' Если эта переменная установлена, ее значение - время ожидания ввода в секундах, перед выполнением прерывания команды.
- $FIGNORE Эта переменная ~ список суффиксов, которые необходимо игнорировать при завершении имени файла. Обычно она имеет значение подобное .о:'~'.
Оболочка bash имеет также несколько переменных приглашения, которые определяют облик приглашения. Они освещаются в разделе "Приглашение".
Приглашение
Приглашение - это строка, отображаемая оболочкой bash, когда она выполняется в интерактивном режиме и готова считать или завершить команду. Bash поддерживает четыре различные приглашения: $PS1, $PS2, $PS3 и $PS4. Из них обычно только переменные $PS1 и $PS2 представляют интерес в интерактивных оболочках. Первичная строка приглашения является значением $PS1 и отображается тогда, когда bash готова считать команду. Вторичное приглашение $PS2 отображается, когда bash нуждается в дополнительном вводе для завершения команды, которую уже начала считывать. Переменная $PS3 содержит приглашение, которое отображается при использовании оператора select. Переменная $PS4 отображается только во время трассировки выполнения. Большинство пользователей не слишком часто используют переменные $PS3 и $PS4, и поэтому обычно в инициализационных файлах этим переменным не задается никаких значений. Все приглашения настраиваются одинаково и воспринимают следующие последовательности специальных символов:
\d Дата в формате "День_недели Месяц Число" (например, "Tue May 26")
\h Имя хоста вплоть до первой точки (.)
\Н Полное имя хоста
\s Имя оболочки
\t Текущее время в 24-часовом формате ЧЧ:ММ:СС
\Т Текущее время в 12-часовом формате ЧЧ:ММ:СС
\@ Текущее время в 12-часовом формате am/pm (до полудня/после полудня)
\и Имя текущего пользователя
\v Версия bash (например, 2.00)
\V Вариант версии оболочки bash (например, 2.00.0)
\w Текущий каталог
\W Базовое имя текущего каталога
\! Номер текущей команды в файле истории
\# Номер текущей команды с момента вызова оболочки, который обычно отличается от номера в истории
\$ Если действующим UID является 0, то #, в противном случае - $.
Ниже приведены несколько примеров обычных значений переменной $PS1 и соответствующие приглашения:
PSl="\s-\v\$ "bash-2.00$
PSl="\h \#\$ "soda 2$
PSl-"\h:\w [\#]\$ " soda:- [3]$
PSl="\t \H \#\$ " 19:10:21 soda.berkeley.edu 16$
Кроме этих последовательностей специальных символов в приглашения могут включаться переменные и команды, которые раскрываются, как описано в соответствующем разделе.
Bash также распознает переменную $PROMPT_COMMAND, в которой может быть задано имя команды, подлежащей выполнению перед установкой первичного приглашения. Некоторые пользователи предпочитают использовать эту переменную для отображения обычных приглашений того компьютера, на котором они работают:
PROMPT_COMMAND="uptime | cut -d: -f4"
Значение переменной $PROMPT_COMMAND может быть равным любой команде оболочки, от легкомысленного PROMPT_COMMAND="fortune" до грозного PROMPT_COMMAND="/bin/rm -rf *".
Команды set и shopt
Встроенные команды set и shopt могут использоваться для настройки поведения bash. Эта настройка обычно выполняется в инициализационном файле. Встроенная команда set доступна в версиях bash l.x и 2.0-х, а встроенная команда shopt - только в версии bash 2.0.X.
Синтаксис команды set выглядит следующим образом: set [+/-}[options]. Например
set -a
set -о allexport
устанавливает опцию allexport, a
set +a
set +о allexport
отменяет установку опции allexport.
Команда set может использоваться интерактивно из командной строки для изменения поведения оболочки или запускаться в инициализационных файлах и сценариях оболочки. Ниже приводится перечень опций, распознаваемых командой set (эквивалентные опции приводятся вместе):
- -а
- -о allexport Эти опции заставляют оболочку bash автоматически помечать все переменные для экспорта при их создании или изменении.
- -b
- -о notify Эти опции заставляют bash сообщать о состоянии прерванных фоновых задач немедленно, а не ожидать отображения следующего первичного приглашения.
- -е
- -о errexit При указании этих опций bash будет осуществлять выход, как только простая команда осуществит выход с ненулевым состоянием. Оболочка не будет выполнять выход, если команда является частью цикла, находится в списке условий или если возвращаемое значение команды инвертируется с помощью операции !.
- -f
- -о noglob Эти опции отменяют использование переменной пути для поиска команд и проч.
- -h
- -о hash all Эти опции заставляют оболочку bash запоминать размещение команд, которые ранее были найдены для выполнения. Эти опции активизированы по умолчанию.
- -n
- -о поехес Эти опции заставляют неинтерактивные оболочки bash считывать команды без их выполнения и часто используются для проверки синтаксиса сценария оболочки.
- -v
- -о verbose Эти опции заставляют bash отображать строки ввода после их считывания. Эти опции работают аналогично опции -verbose.
- -B
- -о braceexpand Эти опции позволяют оболочке bash выполнять раскрытие фигурных скобок. Они активизированы по умолчанию.
- -С
- -о noclobber Если эти опции установлены, bash не будет перезаписывать существующий файл при выполнении перенаправления. Это может быть изменено посредством оператора >!
- -H
- -о histexpand Эти опции активизируют использование механизма истории, и по умолчанию они установлены для интерактивных оболочек.
- -о emacs Эта опция заставляет оболочку bash использовать для редактирования командной строки команды редактора emacs. По умолчанию эта опция активизирована для всех интерактивных оболочек за исключением вызванных с опцией -noediting.
- -history Эта опция активизирует историю команд и по умолчанию используется для интерактивных оболочек.
- -о ignoreeof Эта опция устанавливает значение переменной $IGNOREEOF, равным 10.
- -о posix Эта опция принудительно переключает bash в режим posix. Она оказывает действие, аналогичное вызову опции -posix.
- -о vi Эта опция заставляет bash использовать для редактирования командной строки команды редактора vi.
Если команда set -о дается без других аргументов, выводится список всех установленных в данный момент опций. Если set дается без каких-либо аргументов, отображаются все инициализированные в настоящий момент переменные.
Встроенная команда shopt в bash 2.0.х позволяет устанавливать еще несколько опций, воздействующих на поведение оболочки bash. В целом опции оболочки устанавливаются командой shopt -s, а отмена установки опции осуществляется посредством команды shopt -u. Например:
shopt +s cdable_vars
активизирует опцию оболочки cdable_vars, a
shopt +u cdable vars
отменяет ее. Вот некоторые опции оболочки, которые могут быть установлены с помощью команды shopt:
- cdable_vars Установка этой опции оболочки позволяет команде cd заключить, что данный аргумент, не являющийся каталогом, является именем переменной, значение которой - имя каталога, в который нужно перейти.
- cdspell Если эта опция оболочки установлена, cd будет исправлять небольшие опечатки в написании пути и отображать правильный путь перед сменой каталога.
- checkhach Если эта опция установлена, bash будет проверять, существуют ли команды, находящиеся в хэш-таблице, прежде чем пытаться выполнить их. Далее поиск производится в $РАТН.
- checkwinsize Установка этой опции оболочки позволяет bash проверять размер окна после исполнения каждой команды и, если необходимо, изменять значения переменных LINES и COLUMNS.
- cmdhist Установка этой опции оболочки позволяет bash сохранять все строки многострочных команд в одной записи истории .
- lithist Если эта опция и опция оболочки cmdhist установлены, многострочные команды сохраняются в истории с символами новых строк.
- histappend Если эта опция оболочки установлена, список истории дописывается к файлу истории, а не перезаписывает его.
- histverify Установка этой опции заставляет bash после подстановки команды из файла истории перезагружать строку для дальнейшего редактирования.
- dotglob Если эта опция оболочки установлена, bash вставляет в результаты раскрытия пути имена файлов, начинающиеся с точки (.).
- hostcomplete Если эта опция оболочки установлена, bash будет делать попытки выполнить завершение имени хоста при встрече слова, начинающегося с @. Эта опция оболочки активизирована по умолчанию.
- Interactive_comments Установка этой опции оболочки позволяет вводить комментарии в интерактивной оболочке. Эта опция оболочки активизирована по умолчанию.
- mailwarn Если эта опция оболочки установлена, bash выполняет проверку на предмет наличия новой почты.
- promptvars Если эта опция оболочки установлена, строка приглашения подвергается стандартной интерпретации. Эта опция оболочки активизирована по умолчанию.
- expand_aliases Если эта опция оболочки установлена, она позволяет bash подставлять значения псевдонимов.
Команда shopt также распознает опцию -р, выводящую список всех установленных опций оболочки, и опцию -q, подавляющую вывод.
Псевдонимы
Псевдонимы - удобный способ сокращения длинных команд в интерактивных оболочках, выполнения нескольких команд посредством ввода одного слова или вызова определенных команд некоторыми часто используемыми опциями. В оболочке bash псевдонимы создаются (устанавливаются) посредством использования команды alias и уничтожаются посредством команды unalias. Общий синтаксис аналогичен оболочке sh:
alias name=value
Когда bash встречает команду, то проверяет, не содержит ли команда известные псевдонимы. Если да, то эти слова замещаются соответствующим текстом псевдонима. Результирующий текст также проверяется на предмет наличия псевдонимов, но рекурсивная подстановка не выполняется. Таким образом, при объявлении псевдонима подобного
alias rm="rm -i"
и при вводе rm в качестве имени команды, как только rm -i введено, rm в результирующем тексте не интерпретируется.
Простейшие типы псевдонимов - те, которые используются для небольшого изменения работы команды. Например, следующие псевдонимы просто выполняют данную команду, каждый раз с некоторыми опциями по умолчанию:
alias m="more"
alias mv="mv -i" # выводит запрос на перезапись файла при перемещении файлов alias ср="ср -i"" # выводит запрос на перезапись файла при копировании файлов alias alias ls="ls -aFc"" # отображает в столбцах все файлы и их типы файлов
Простые псевдонимы также удобны при исправлении распространенных ошибок при наборе имен команд:
alias chomd="chmod" alias mroe="more"
Оболочка bash поддерживает также более сложные псевдонимы, подобные
alias mq="/usr/lib/sendmail -bp" # вывод текущей почтовой очереди alias psme="{ ps -ael | head -1 ; ps -ael | grep \" ${UID} \" ; } | more"
Псевдонимы могут быть замещены посредством предварения имени псевдонима обратной косой чертой (\), посредством встроенной команды command или вводом полного пути к исполняемому модулю. Если rm - псевдоним команды rm -i, то каждая из следующих строк будет замещать собой этот псевдоним:
\rm
command rm
/bin/rm
Псевдонимы оболочки не поддерживают двух свойств: аргументов и присваивании. Если необходимо использовать эти свойства, придется создавать соответствующую функцию оболочки.
Функции
Функции служат той же цели, что и псевдонимы, но имеют гораздо большие возможности; они похожи на сценарии оболочки. Общий синтаксис определения функции следующий: function name () { list; }. Ключевое слово function не является обязательным, и функции часто записываются как
name () {
list ;
}
Когда имя функции name дано без круглых скобок, связанный с ним список команд выполняется. Круглые скобки после имени функции name используются оболочкой для идентификации функций и не означают, что аргумента у функции не существует.
Простейшие функции подобны псевдонимам. Например, следующие псевдоним и функция эквивалентны:
alias mq=/usr/lib/sendmail -bp" mq () { /usr/lib/sendmail -bp ; }
Функции также используются, когда в среде необходимо выполнить небольшие изменения. Например, следующая функция изменяет значение переменной $IFS таким образом, чтобы каждый каталог в пути выводился в отдельной строке:
prinpath ()
{
( IFS=;;
for i in $PATH;
do
echo $i;
done )
}
В большинстве случаев функции используются для выполнения более сложных задач, когда требуются аргументы. Простейшим подобным примером является функция, которая использует только свой первый аргумент, $1:
mkcd ()
{
if [ -n "$1" ] && mkdir "$1"; then
cd "$1";
echo "Created" 'pwd';
fi }
Ниже приводятся примеры функций, которые обрабатывают все переданные им аргументы:
myuuencode ()
{
if [ -n "$1" ]; then
{ for i in "$@";
do
if [ -e "$i" ] && uuencode $i $i >${i}.uu; then echo "uuencoded $i to ${i}.uu";
else echo "unable to uunencode $i";
fi;
done )
fi
}
murder ()
{
( for pattern in "$@";
do
ps -ef | grep "$pattern" | while read user pid junk; do
kill -HUP "$pid";
done;
done )
}
Первая функция - удобный способ кодирования файлов с помощью утилиты uuencode без необходимости ввода длинных команд, а вторая - быстрый способ прерывания процессов, соответствующих определенным шаблонам.
Одна из важных особенностей функций та, что они могут вызываться рекурсивно. Поскольку не существует ограничений на число рекурсивных обращений, простое замещение псевдонима функцией подобно следующему:
ср () { ср -i ; }
не рекомендуется.
Пример инициализационного файла Этот раздел содержит пример инициализационного файла .bash__profile.
# .bash_profile
# Для версий 1.14.7 или последующих
# установка маски создания файла пользователя
umask 022
# установка PATH, пути поиска команд
export PATH=/bin:/usr/bin:/usr/sbin:/usr/etc:/usr/ucb:/usr/local/bin
# Исполнение команд для интерактивных оболочек. Альтернативный тест: if tty -s; then
if [ -t ] ; then
# установка некоторых параметров/ специфичных для терминала
stty -decctlq >& /dev/null
stty erase '^H' kill '^U' intr '^C'
# установка TERM, типа терминала, равным vtlOO, если TERM не "действителен"
case "$TERM" in
*term)
TERM=xterm
;;
network|diaiup|unknown)
TERM=vtlOO
;;
esac
export TERM
# установка MANPATH, пути поиска страницы руководства MANPATH="/usr/man:/usr/local/man"
if [ -d "$HOME/man" ] ; then
MANPATH="$MANPATH:$HOME/man"
fi
export MANPATH
# установка LD_LIBRARY_PATH, пути поиска библиотеки
export LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/lib
# установка uid, требуемого для некоторых сценариев csh (например, which) export uid="$UID"
# установка CDPATH, пути поиска для cd
export CDPATH=.:~:~/docs
# установка переменных, связанных с редактированием
if type emacs >/dev/null 2>&1; then
EDITOR=emacs
else
EDITOR=vi
fi
FCEDIT="$EDITOR"
VISUAL="$EDITOR"
export EDITOR VISUAL FCEDIT
# установка утилиты постраничного вывода PAGER для просмотра файлов,
# man-страниц и т.п...
if type less >/dev/null 2>&1; then
PAGER="less -s"
else
PAGER="more -s"
fi
export PAGER
# установка MAILCHECK, временных интервалов между проверкой почты export MAILCHECK=$((60*10))
# установка PS1 и PS2, строк первичного и вторичного приглашения
PSl="\h \#\$
PS2="\#> "
export PS1 PS2
# установка переменных, связанных с историей
export HISTCONTROL=ignoredups
# установка PIGNORE, суффиксов, подлежащих игнорированию при
#завершении имен файлов
export FIGNORE=.out:.о:'~'
# установка опций
set -о notify ignoreeof nonclobber
# установка/отмена установки необязательного поведения оболочки
# доступно в V2.00.0 или последующих
if type shopt > /dev/null 2>&1 ; then
shopt -s checlchash checkwinsize cmdhist lithist dotglob
shopt -s histappend histreedit histverify
if [ -n "$MAILCHECK" ] ; then
shopt -s mailwarn
fi
fi
fi
Командная строка и история
В последующих разделах освещается взаимодействие с командной строкой. При рассмотрении основных положений в этом разделе предполагается, что используется редактирование командной строки в режиме emacs.
Командная строка
В интерактивных оболочках команды вводятся в ответ на приглашение. Bash воспринимает строку для выполнения при вводе символов -line: newline (\n) или return. Например, при вводе в приглашении такой команды, как date, в интерактивной оболочке, bash делит ее на простые команды с аргументами. Если вводится полный путь команды, bash пытается выполнить ее; в противном случае bash сперва пытается найти функцию оболочки, соответствующую команде, затем встроенную команду оболочки и, наконец, команду, расположенную где-либо в пути поиска, приведенном в переменной $РАТН.
Редактирование командной строки
Часто при вводе команд допускаются ошибки. Bash обеспечивает дружественный интерфейс для исправления этих ошибок, совсем как в ksh и tcsh. Используя эти ключевые команды, пользователь может переместить курсор в любую позицию командной строки и отредактировать текст в этой позиции.
В последующих описаниях команд символ С- используется для указания управляющей клавиши control (префикса), а М- используется для указания метаклавиши meta (префикса); все остальные клавиши указаны буквально. Если приведены два управляющих символа, должны использоваться оба. Например, управляющая последовательность C-f означает нажатие клавиши f при удержании нажатой клавиши control, a управляющая последовательность C-q C-v означает нажатие клавиши q при нажатой клавише control, a затем нажатие клавиши v при нажатой клавише control.
Ниже приведен список команд для перемещения по командной строке:
- С-а Перемещает курсор к началу команды
- С-е Перемещает курсор к концу команды
- C-f Перемещает курсор на один символ вперед. На терминалах/клавиатурах, которые поддерживают клавиши-стрелки, стрелка вправо может использоваться для перемещения курсора на один символ вперед.
- С-b Перемещает курсор на один символ назад. На терминалах/клавиатурах, которые поддерживают клавиши-стрелки, стрелка влево может использоваться для перемещения курсора на один символ назад.
- M-f Перемещает курсор на одно слово вперед.
- М-b Перемещает курсор на одно слово назад.
- С-1 Очищает экран и помещает текущую строку в его верхней части. Это эквивалентно команде clear.
Bash допускает существенное редактирование команд посредством удаления, вырезания и вставки текста. Вырезание и вставка аналогичны вырезанию и вставке в большинстве текстовых процессоров. Эти команды следующие:
- delete Удаляет символ слева от курсора.
- C-d Удаляет символ под курсором. Если под курсором нет никакого символа, печатается символ EOF.
- C-k Вырезает весь текст от позиции курсора до конца строки.
- С-х delete Вырезает весь текст строки.
- С-u Вырезает весь текст между курсором и началом строки.
- С-у Вставляет вырезанный текст
Bash поддерживает также следующие команды, связанные с редактированием:
- М-u Изменяет буквы текущего слова на прописные.
- М-1 Изменяет буквы текущего слова на строчные.
- C-q, C-v Добавляет следующий символ, введенный в буквенном режиме.
- C-g Прекращает редактирование
- С-_ Отмена
- С-х С-u Отмена
- М-r Отменяет все изменения, выполненные в текущей строке.
- С-] Считывает символ и перемещает курсор к следующему такому же символу.
- М-С-] Считывает символ и перемещает курсор к предыдущему такому же символу.
В некоторых случаях, при одновременном редактировании нескольких команд, инструментальных средств редактирования командной строки недостаточно. Для подобных случаев bash обеспечивает встроенную команду fc. Эта команда вызывает редактор для редактирования команды и запускает отредактированную команду сразу по выходе из редактора. По умолчанию fc вызывает редактор и помещает последнюю выполненную команду в его буфер, но команде fc можно указать номер подлежащей редактированию команды и используемый редактор. Например,
fc 10
вызовет редактор для десятой выполненной команды с момента запуска оболочки, а
fc -10
вызовет редактор для команды, которая была выполнена 10 команд назад. Вызываемый редактор может быть указан посредством опции -е, за которой следует имя редактора. Например,
fc -е emacs
вызовет emacs и поместит последнюю команду в буфер для редактирования. Если опция -е не вводится, в качестве имени редактора используется значение переменной $FCEDIT, если оно существует; в противном случае в качестве имени редактора используется значение $EDITOR. Если ни $FCEDIT, ни $EDITOR не установлены, в качестве редактора используется vi.
Завершение
В дополнение к командам редактирования bash также завершает текст перед курсором. Оболочка bash обладает способностью завершать имена переменных, имена пользователей, имена хостов, команд и файлов. Для слов, начинающихся с символа $ делается попытка выполнить завершение переменных. Для слов, начинающихся с символа ~, bash делает попытку завершить имя пользователя. Для слов, начинающихся с @, делается попытка завершить имя хоста. Для остальных слов сперва предпринимается попытка завершения команды, а затем - завершения имени файла. В целом, команда завершения дается при каждом нажатии клавиши tab. Некоторыми другими командами завершения являются:
- М-? Перечисляет все возможные завершения.
- М-* Вставляет в позицию курсора строку, содержащую все возможные завершения.
- М-/ Заставляет bash выполнить завершение имени файла.
- М-~ Заставляет bash выполнить завершение имени пользователя.
- М-$ Заставляет bash выполнить завершение переменной.
- М-@ Заставляет bash выполнить завершение имени хоста.
- М-! Заставляет bash выполнить завершение команды. Bash попытается найти завершения, являющиеся псевдонимами, зарезервированными словами, функциями оболочки, встроенными командами и исполняемыми модулями.
Повторный вызов команд из списка истории
История - это список команд, которые выполнялись ранее. По умолчанию bash хранит в истории до 500 команд, начиная с команды 1 и увеличивая номер на 1 при каждом принятии команды. Как только команда принята (например, при вводе return), она дописывается в конец файла истории ~/.bash_history.
Существуют несколько переменных, описанных в разделе, посвященном переменным оболочки, которые могут использоваться для настройки этого механизма. Кроме хранения команд в истории, bash распознает следующие команды повторного вызова ранее выполнявшихся команд:
- С-р Повторно вызывает предыдущую команду в истории. На терминалах/клавиатурах, которые поддерживают клавиши стрелок, стрелка вверх может использоваться для повторного вызова предыдущей команды.
- С-n Повторно вызывает следующую команду в истории. На терминалах/клавиатурах, которые поддерживают клавиши стрелок, стрелка вниз может использоваться для повторного вызова следующей команды.
- М-< Выполняет переход к первой команде в истории.
- М-> Выполняет переход к последней команде в истории.
- С-r Просматривает историю в обратном направлении, начиная с текущей строки (просматривает предыдущие команды). Этот процесс может оказаться медленным, если список истории велик.
- C-s Просматривает историю вперед, начиная с текущей строки.
Переменные истории
Bash поддерживает несколько специальных переменных только для чтения, относящихся к выполнявшимся командам. Ими являются:
- $? Значение этого параметра - значение выхода последнего выполнявшегося конвейера.
- $$ Значение этого параметра - номер процесса текущей оболочки.
- $! Значение этого параметра ~ номер процесса последнего выполнявшегося фонового процесса.
- $0 Это имя текущей оболочки или ссылки на нее в сценарии оболочки; это имя, с которым вызывался сценарий.
Подстановка команд из списка истории
Во многих случаях повторный вызов и редактирование команд может оказаться не простым делом. Для подобных случаев bash обеспечивает средства для манипулирования (подстановки) историей, используя операции, подобные операциям оболочки chs. Подстановка истории начинается, когда bash встречает операцию !, за которой не следуют символы пробела, = или (. Если за операцией ! следует какой-либо из этих символов, bash выполняет операцию отрицания, а не подстановку истории.
Простой подстановкой истории является операция !, за которой следует номер команды, которую необходимо повторно выполнить. Например, операция
!213
выполнит команду, хранящуюся в истории под номером 213. В общем случае такую подстановку истории записывают как !n, где n - номер команды. Если п отрицательно, команда вызывает и выполняет n-ю команду, предшествующую текущей. Например, следующая операция:
!-10
выполнит команду, которая была выполнена 10 команд назад, а последняя выполненная команда может быть повторно вызвана с помощью
'-1
Поскольку повторный вызов ранее выполнявшихся команд - распространенная задача, bash имеет для нее управляющую последовательность быстрого доступа !!. Кроме того, команда может быть повторно вызвана из истории посредством ввода части строки, с которой она начинается или которую содержит. Например, последняя команда mail может быть вызвана повторно операцией
Общий синтаксис повторного вызова команд, начинающихся с конкретной строки: ! string. В предыдущем примере подстановка истории не вызовет повторно команды, содержащие строку mail, как например, sendmail или rmail, но повторно вызовет команду mailtool, если она появляется в истории перед командой mail. Bash может вызывать команды, содержащие конкретные строки, если подстановка истории имеет форму !?string?. Например,
!?host?
может использоваться для повторного вызова команд hostname, gethostname, ypcat hosts и echo $host
Иногда простого повторного вызова команд недостаточно, поэтому bash поддерживает несколько подстановок истории частичного повторного вызова и замещения. Простейшей из них является замещение ^string1^strillg2^, которая в предыдущей команде замещает строку string1 строкой string2. Если выполняется команда
xv koala.gif
а затем должно быть просмотрено изображение kangaroo.gif, может быть использована следующая быстрая подстановка:
^koala^ kangaroo^
Более сложные операции замещения могут повторно вызывать аргументы, переданные предыдущим командам. Простейшая из них !:0, которая повторно вызывает имя предшествующей команды. Например, если вводится команда
cpwd () { if [ -n "$1" ] ; then cd "$1"; fi ; pwd }
и отформатированная версия должна быть просмотрена посредством команды type, требуемый результат будет получен посредством следующей команды:
type !:0
Как только отформатированная функция просмотрена, может потребоваться ее использование, поэтому следующая команда:
!:^ /bin
повторно вызовет имя функции, которая была передана в качестве первого аргумента команды type, т.к. подстановка !:^ повторно вызывает первый аргумент, переданный команде. Иногда необходимо вызвать последний аргумент, переданный команде, для этого может использоваться подстановка !:$. Эти операции - сокращенные варианты более общей подстановки !:n, которая повторно вызывает n-й аргумент, переданный команде. Если бы требовался третий аргумент команды, нужно было бы использовать подстановку !:3. Часто недостаточно просто повторно вызвать один аргумент команды. Например, если бы выполнялась команда
xman -background white -geometry 135х55
и требовался бы параметр такого же цвета фона и геометрии, подстановка
perfmeter !*
дала бы требуемые результаты, поскольку подстановки !* и !:* используются для повторного вызова всего списка аргументов, переданных команде. Эти подстановки - специальные формы подстановок истории !:х-у, которые повторно вызывают все аргументы между х и у, переданные команде. Например, если дается следующая команда:
javac -d . -O.rectPanel.java
и второй и третий аргументы (флаги компилятора) требуются для последующей компиляции, подстановка
javac !:1-3 javaStarDate.java
даст требуемый результат.
В общем виде подстановки истории могут быть записаны, как !string:option, где option - ранее описанные опции 0, n, ^, х-у и *. Например, если выполняется следующая команда finger:
finger ranga@soda.berkeley.edu sriranga@ocf.berkeley.edu
и по выполнении нескольких других команд почта должна быть отправлена этим пользователям, следующая подстановка
mail 'finger:*
даст надлежащий результат.
Резюме
Bash - мощная оболочка, популярная как среди начинающих, так и среди опытных пользователей, поскольку она обеспечивает множество полезных свойств, таких как редактирование командной строки и завершение имен файлов. Ее сила и популярность возрастают благодаря интеграции свойств, присущих оболочкам Bourne, Kom и С. Bash также доступна на многих системах, отличных от UNIX, поэтому знания и навыки использования Bash обязательно пригодятся любому пользователю.
Источники информации
При написании этой главы использовались следующие источники:
Manual Page BASH(l), Free Software Foundation, 1996
BASH FAQ version 2.1, 1996