Немного о bash и его настройках

Автор: Алексей Федорчук

Командной оболочке bash посвящено бессчётное число материалов, к которым я, не являясь ни ее любителем, ни, тем более, знатоком, мало чего могу добавить. Однако bash — наиболее распространенная среди пользователей Linux командная оболочка, выступающая в этой ОС к тому же общесистемной и умолчальной. Популярна она, насколько мне известно, и среди пользователей иных POSIX-систем: так, она является единственной оболочкой в базовой установке OpenSolaris. А ныне принята она и в MacOS X, где сменила традиционную для BSD-систем csh.

Поэтому в настоящей заметке я собрал всё, что мне представляется важным при использовании bash — точнее, описание тех её возможностей, которые использую сам, когда мне приходится иметь дело с этой командной оболочкой. Но для начала я должен выразить благодарность Сергею Майкову aka Madskull, Александру Баракину aka sash-kan и многим другим участникам обсуждения тем, связанных с bash, на Юниксксфоруме и POSIX.ru.

Из командной строки терминала можно прямой командой запустить любое приложение графического режима. Однако обычно так не делают — терминал предназначен в первую очередь для запуска утилит командной строки и консольных программ. И первейшей такой программой выступает сама командная оболочка — среда для исполнения директив CLI, о которых говорилось в разделе 11.

Как уже говорилось, во всех дистрибутивах Linux в качестве пользовательской командной оболочки выступает bash, что расшифровывается как «еще одна оболочка Борна», «заново рожденный шелл» и тому подобным образом. Она происходит от первого шелла первозданного Unix’а, разработанного Борном (которая именовалась просто shell или sh), но снабжена многими дополнительными возможностями. Эта оболочка оказалась тесно интегрирована с операционной системой Linux: именно bash волею судеб стал одной из первых программ, которые Линус запустил поверх своего новосозданного ядра. И потому идеи bash-скриптинга пронизали Linux до самых его оснований — достаточно сказать, что большинство сценариев инициализации в каталоге /etc представляют именно bash-скрипты.

Однако роль bash не исчерпывается скриптингом — в первую очередь это среда для выполнения пользовательских команд. Различаются команды внешние и встроенные команды оболочки. Bash поддерживает множество таких встроенных команд (полный список можно увидеть на man-странице bash-builtins).

Оболочка bash поддерживает все интерактивные возможности, столь важные для пользователя, как то: автодополнение для команд и путей к файлам, историю оных (включая средства инкрементного поиска), мощные возможности навигации и редактирования командной строки. Важно, что существует дополнительный пакет bash-completion (в Kubuntu он устанавливается по умолчанию): установка его обогащет базовую оболочку множеством опциональных средств настройки автодополнения (в том числе и для командных аргументов). Правда, чтобы эта дополненная оболочка была по настоящему удобной и функциональной, нужно приложить некоторые усилия по ее настройке, чем мы и займемся в данном параграфе.

Для настройки шелла важно понимать разницу между интерактивным и неинтерактивным шеллами. Первый — это любой экземпляр командной оболочки, запущенный пользователем непосредственно. Если этот экземпляр запускается при входе пользователя в систему, его называют login shell (то есть главная пользовательская оболочка). Очевидно, что login shell — также интерактивен, однако в сеансе работы каждого пользователя он будет единственным. Просто же интерактивных шеллов можно запустить сколько угодно — например, в каждом терминальном окне или вкладке терминальных программ типа konsole будет функционировать собственная копия интерактивного шелла.

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

Схема настройки bash предусматривает наличие пары файлов /etc/profile и /etc/bashrc (для пользовательского шелла и просто интерактивного его экземпляра), а также соответствующих им пользовательских конфигов — ~/.bash_profile и ~/.bashrc. При авторизации первым в любом случае считывается общесистемный профильный файл /etc/profile, вслед за ним — пользовательский профильный файл ~/.bash_profile, после чего происходит обращение к ~/.bashrc. Файл /etc/profile может занимать особое положение — в него часто помещают переменные окружения (например, локально-зависимые), которые должны быть общими для всех пользователей данной системы. Пользовательские же настройки определяются в файлах ~/.bash_profile и ~/.bashrc. Обычно в ~/.bash_profile определяются переменные окружения, которые должны действовать для всех дочерних процессов, а в ~/.bashrc — параметры, всегда требуемые в в интерактивном режиме (например, псавдонимы).

Редактирование командной строки в bash обеспечивается отдельным пакетом — библиотекой функций readline. Она имеет собственные конфигурационные файлы, общесистемный /etc/inputrc и пользовательский ~/.inputrc.

Впрочем, в Kubuntu, ориентированном на графичесёкий режим и, следовательно, использование эмулятора терминала с интерактивным шеллом, не являющимся, тем не менее, шеллом пользовательским (login shell), ~/.bash_profile играет сугубо служебную роль, и содержимое его сводится к отработке файла ~/.bashrc:

# include .bashrc if it existsif [ -f ~/.bashrc ]; then

. ~/.bashrc

fi# set PATH so it includes user's private bin if it existsif [ -d ~/bin ] ; then

PATH=~/bin:"${PATH}"

fi

в котором и выполняются все пользовательские настройки.

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

Так, по умолчанию в bash автодополнение клавишей табулятора не работает, например, в аргументах многих команд, таких, как sudo или man. Решается эта задача очень просто: достаточно файл ~/.bashrc внести следующие строки:

# enable bash completion in interactive shells
if [ -f /etc/bash_completion ]; then
 . /etc/bash_completion
fi

После этого автодополнение будет работать буквально везде, где только можно себе представить, например: bash <TAB> — автодополнение названия хоста или dpkg --sea <TAB> — получится dpkg --search.

Если в файл /etc/inpurc (или в ~/inpurc) добавить такие строки:

"e[A": history-search-backward
"e[B": history-search-forward

то набор части команды, например, cd /, и последующий перебор стрелками <Up> и <Down> истории команд повлечет извеление из буфера истории только тех из них, которые начинаются на cd /.

Очень полезно в файле ~/.bashrc определить псевдонимы (aliases) для некоторых часто используемых команд. Псевдоним — это просто некоторое условное имя, подменяющее определенную команду с теми ее опциями, которые мы используем чаще всего. Причем, что характерно, псевдоним команды может совпадать с ее именем. То есть, например, — набирая просто ls, мы получаем список файлов не в умолчальном формате, а в том, в каком угодно нам.

Устанавливаются псевдонимы одноименной командой alias, в качестве аргументов которой выступают имя псевдонима и его значение, соединенные оператором присваивания (именуемым в просторечии знаком равенства). А именно, если мы хотим ныне, и присно, и во веки веков видеть вывод команды ls в цвете, нам достаточно вписать в конфиг bash такой псевдоним:

$ alias ls='ls --color=auto'

Вспомним команды типа cp и mv, которыми мы можем скопировать или переместить какие-то файлы из каталога в каталог. А что произойдет, если чисто случайно в целевом каталоге уже имеются файлы, одноименные копируемым/перемещаемым? Произойдет штука, могущая иметь весьма неприятные последствия: файлы в целевом каталоге будут заменены новыми, теми, что копируются туда или перемещаются. То есть исходное содержание этих файлов будет утрачено — и утрачено безвозвратно.

Разумеется, иногда так и нужно: например, при резервном копировании старые версии файлов и должны быть заменены более свежими их вариантами. Однако такое приемлемо далеко не всегда. И потому в большинстве команд, связанных с необратимыми изменениями файловой системы, предусматривается специальная опция — -i (или --interactive). Если задать эту опцию с командой cp или mv, то при совпадении имен исходного и целевого файлов будет запрошено подтверждение на выполнение соответствующего действия. И, дабы не держать в голове необходимость опции -i, для команд cp и mv (а также для команды rm, эта операция также практически необратима) целесообразно определить одноименные им псевдонимы такого вида:

alias cp='cp -i'alias mv='mv -i'alias rm='rm -i'

Но что, если заведомо известно, что сотни, а то и тысячи файлов целевого каталога должны быть именно переписаны новыми своими версиями? В этом случае можно прибегнуть к опции -f (или --force). Которая, отменяя действие опции -i, предписывает принудительно переписать все файлы целевого каталога их обновленными тезками. И никто не мешает нам на этот случай создать еще один псевдоним для команды cp, например:

alias cpf='cp -f'

Второй способ временн избавиться от подтверждения на копирование или удаление файлов — просто отменить псевдоним. Что делается командой — unalias. То есть, дав директиву

$ unalias cp

мы вернем команде копирования ее первозданный смысл. Ну а узнать, какие псевдонимы у нас определены в данный момент, и каковы их значения, еще проще: команда

$ alias

без опций и аргументов выведет полный их список.

В общем, о bash можно было бы говорить еще долго. Однако достаточно заметить, что почти в любой толстой книге про Linux, когда речь заходит о командных оболочках вообще, как правило, имеется ввиду именно bash. Немало сведений о ней есть и в Сети, в том числе в русскоязычном ее сегменте.