Bash (Русский)

From ArchWiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
Состояние перевода: На этой странице представлен перевод статьи Bash. Дата последней синхронизации: 10 июля 2021. Вы можете помочь синхронизировать перевод, если в английской версии произошли изменения.

Bash (Bourne-again Shell) — командная оболочка/язык программирования проекта GNU. Название представляет собой отсылку к предшественнику, существовавшей некогда командной оболочке Борна (Bourne shell). Bash работает в большинстве UNIX-подобных операционных систем, в том числе и в GNU/Linux.

В Arch Linux Bash является командной оболочкой, используемой по умолчанию.

Запуск

Поведение Bash зависит от способа, каким он был запущен.

Если Bash был вызван в TTY в процессе работы команды login, демоном SSH или другим схожим образом, то он считается оболочкой входа (login shell). Этот режим также можно выбрать флагом -l/--login.

Bash считается интерактивной оболочкой (interactive shell), если его стандартные потоки ввода/вывода/ошибок подключены к терминалу (например, при запуске в эмуляторе терминала), причём запуск выполнялся без опции -c и не с неопциональным аргументом (вроде bash скрипт). Все интерактивные оболочки при запуске считывают файлы /etc/bash.bashrc и ~/.bashrc, а интерактивные оболочки входа — также /etc/profile и ~/.bash_profile.

Примечание: В Arch исполняемый файл /bin/sh (использовался в оболочке Борна) заменён символической ссылкой на /bin/bash. Если запустить Bash командой sh, то он будет вести себя маскимально приближенно к "настоящему" sh, в том числе и в смысле POSIX-совместимости.

Файлы настроек

В зависимости от способа запуска Bash считывает и исполняет определённый набор файлов. Подробнее см. раздел Bash Startup Files справочного руководства GNU Bash.

Файл Описание Оболочки входа (см. примечание) Интерактивные оболочки (не входа)
/etc/profile Системный, считывает и исполняет файлы /etc/profile.d/*.sh и /etc/bash.bashrc с настройками приложений. Да Нет
~/.bash_profile Пользовательский, исполняется после /etc/profile. Если не существует, проверяются ~/.bash_login и ~/.profile (в указанном порядке). Файл-образец /etc/skel/.bash_profile содержит также указание на исполнение файла ~/.bashrc. Да Нет
~/.bash_logout Пользовательский, исполняется после выхода из оболочки входа. Да Нет
/etc/bash.bash_logout Системный, исполняется после выхода из оболочки входа. Зависит от флага компиляции -DSYS_BASH_LOGOUT="/etc/bash.bash_logout". Да Нет
/etc/bash.bashrc Системный, исполняет файл /usr/share/bash-completion/bash_completion. Зависит от флага компиляции -DSYS_BASHRC="/etc/bash.bashrc". Нет Да
~/.bashrc Пользовательский, исполняется после /etc/bash.bashrc. Нет Да
Примечание:
  • Оболочка входа будет неинтерактивной, если вызывается с флагом --login.
  • Интерактивные оболочки (не входа) не исполняют файл ~/.bash_profile, они наследуют окружение от родительского процесса (которым может быть в том числе и оболочка входа). Подробнее см. GregsWiki:ProcessManagement#On processes, environments and inheritance.

Оболочка и переменные окружения

Поведение оболочки Bash и запущенных в ней программ зависит от переменных окружения. Переменные окружения хранят значения различных параметров оболочки, например, расположение каталогов с исполняемыми файлами или название используемого по умолчанию браузера. При запуске новой оболочки или сценария они наследуют переменные окружения родительского процесса, то есть начинают работу с набором переменных исходной оболочки [1].

Для создания переменной окружения необходимо экспортировать переменную оболочки:

VARIABLE=content
export VARIABLE

или более кратко:

export VARIABLE=content

Переменные окружения принято перечислять в файлах ~/.profile или /etc/profile, чтобы другие Bourne-совместимые оболочки могли их использовать.

Подробнее см. Переменные окружения.

Командная строка

Командная строка Bash работает под управлением библиотеки Readline. Readline позволяет использовать комбинации клавиш в стиле emacs и vi для взаимодействия с командной строкой, например, для перемещения назад и вперёд целыми словами, удаления слов и т.д. Кроме того, Readline отвечает за хранение истории выполненных команд, а также позволяет создавать макросы.

Автодополнение

Автодополнение (tab completion) — завершение вводимых команд по нажатию клавиши Tab (работает по умолчанию).

Одиночное нажатие

Вывести список возможных завершений для частично введённой команды можно несколькими повторными нажатиями клавиши Tab — иногда двумя или тремя. В статье Readline#Быстрое завершение описано, как уменьшить количество нажатий до одного.

Дополнительные программы и опции

По умолчанию Bash позволяет дополнять команды, имена файлов и переменные. Пакет bash-completion добавляет автодополнение для наиболее распространённых команд и их опций, которые можно включить, считав и исполнив файл /usr/share/bash-completion/bash_completion (обычно считывается автоматически в /etc/bash.bashrc). С пакетом bash-completion обычные завершения (вроде $ ls file.*<tab><tab>) будут вести себя немного по-другому, вернуть старое поведение можно командой $ compopt -o bashdefault программа (подробнее см. [2] и [3]).

Настройки для команд

Примечание: Встроенная команда Bash complete может конфликтовать с bash-completion.

По умолчанию Bash помогает завершать только имена файлов, которые следуют за командой. Это можно перенастроить командой complete -c, чтобы дополнялись и определённые команды:

~/.bashrc
complete -c man which

С флагами -cf завершаться будут и команды, и имена файлов после них:

complete -cf sudo

Другие опции автодополнения можно найти в руководстве Bash.

История команд

Автодополнение истории

Клавиши стрелок "вверх" и "вниз" можно назначить для поиска команд в истории (см. Readline#История команд и Синтаксис init-файлов Readline):

~/.bashrc
bind '"\e[A": history-search-backward'
bind '"\e[B": history-search-forward'

Или же, чтобы это работало во всех программах Readline:

~/.inputrc
"\e[A": history-search-backward
"\e[B": history-search-forward

Сокращение истории

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

~/.bashrc
export HISTCONTROL=ignoredups

Если же задать значение erasedups, то дополнительно из истории будут удалены уже существующие дубликаты команд. Подробнее см. руководство Bash.

Отключение истории

Чтобы временно отключить историю, выполните:

$ set +o history

После этого вводимые команды не будут сохраняться в $HISTFILE.

Теперь можно выполнять "чувствительные" в плане безопасности действия, вроде вычисления хэш-суммы пароля (printf secret | sha256sum) или работы с GPG (gpg -eaF secret-pubkey.asc), не опасаясь, что секретный ключ будет сохранён на диск.

Включить историю обратно можно командой

$ set -o history
Совет: Если переменная HISTCONTROL имеет значение ignorespace, команды, начинающиеся с пробела, не будут сохраняться в файл истории. Подробнее см. bash(1) § Shell Variables.

Чтобы отключить всю историю Bash:

~/.bashrc или /etc/profile
export HISTSIZE=0

После необходимо удалить старый файл истории (имейте в виду — команды ниже удалят его безвозвратно):

$ wipe -i -l2 -x4 -p4 "$HISTFILE"
$ ln -sv /dev/null "$HISTFILE"

run-help из Zsh

В Zsh есть возможность вызывать справочное руководство для команды перед курсором по комбинации клавиш Alt+h. В Bash то же самое можно сделать с помощью привязки комбинации клавиш в Readline:

~/.bashrc
run-help() { help "$READLINE_LINE" 2>/dev/null || man "$READLINE_LINE"; }
bind -m vi-insert -x '"\eh": run-help'
bind -m emacs -x     '"\eh": run-help'

Предполагается, что вы используете (стандартный) режим редактирования Emacs.

Псевдонимы

alias (англ. псевдоним) — команда для замены одной строки на другую. Часто используется для сокращения системных команд до аббревиатур или для добавления стандартных аргументов к часто используемым командам.

Пользовательские псевдонимы хранятся в файле ~/.bashrc, а системные (для всех пользователей) — в /etc/bash.bashrc. Примеры можно посмотреть в [4].

Функции Bash подробно описаны в Bash/Функции.

Советы и рекомендации

Настройка приглашения

См. Bash/Настройка приглашения.

Подстветка синтаксиса и подсказки

blesh-gitAUR — редактор командной строки, который написан на чистом Bash и предназначен заменить Readline. Предлагает множество дополнительных возможностей вроде подстветки синтаксиса, подсказок, завершения команд с выпадающим меню, аббревиатур, режима редактирования Vim, хук-функций и т.д.

После установки необходимо считать и выполнить его в интерактивном сеансе. Настройки подробно объясняются в файле ~/.blerc и wiki. Доступна также стабильная сборка bleshAUR.

Command not found

В pkgfile есть хук "command not found", который при вводе неизвестной команды автоматически ищет подходящий исполняемый файл в пакетах в официальных репозиториях.

Чтобы хук заработал, его необходимо считать и исполнить:

~/.bashrc
source /usr/share/doc/pkgfile/command-not-found.bash

После этого при попытке запустить недоступную команду будет выведена следующая информация:

$ abiword
abiword may be found in the following packages:
  extra/abiword 3.0.1-2	/usr/bin/abiword
Примечание: Предварительно необходимо обновить базу данных pkgfile. Подробнее см. pkgfile#Установка.

Существует альтернативный хук "command not found" в виде пакета command-not-foundAUR, результат работы которого выглядит следующим образом:

$ abiword
The command 'abiword' is provided by the following packages:
abiword (2.8.6-7) from extra
	[ abiword ]
abiword (2.8.6-7) from staging
	[ abiword ]
abiword (2.8.6-7) from testing
	[ abiword ]

Отключение комбинации Ctrl+z

Нажатие Ctrl+z в терминале ставит приложение на паузу или закрывает его. Отключить эту комбинацию клавиш можно следующим образом:

#!/bin/bash
trap "" 20
adom

Если после этого во время работы adomAUR вы по ошибке вместо Shift+z нажмёте комбинацию Ctrl+z, то она будет проигнорирована и ничего не произойдёт.

Очистка экрана после выхода

Очистка экрана виртуального терминала после выхода:

~/.bash_logout
clear
reset

Смена каталога при вводе пути

Bash может автоматически добавлять команду cd , если введён только путь к каталогу. Стандартное поведение:

$ /etc
bash: /etc: Is a directory

Если же добавить в .bashrc строку

~/.bashrc
...
shopt -s autocd
...

то произойдёт следующее:

[user@host ~]$ /etc
cd /etc
[user@host etc]$

Autojump

autojump-gitAUR позволяет перемещаться по файловой системе с помощью поиска строк в базе данных с часто посещаемыми путями. Чтобы приложение заработало, после установки необходимо считать и выполнить файл /etc/profile.d/autojump.bash.

Запрет на перезапись файлов

Отключение перезаписи файлов с помощью перенаправления вывода на время текущего сеанса:

$ set -o noclobber

Команда set -C делает то же самое.

Сделать изменения постоянными:

~/.bashrc
set -o noclobber

Принудительно перезаписать файл при установленном noclobber:

$ echo "output" >| file.txt

Решение проблем

Перенос строк при изменении размера окна

При изменении размера окна эмулятора терминала Bash может не получить соответствующий сигнал. В результате выведенный текст будет переноситься некорректно и перекроет приглашение командной строки. Опция оболочки checkwinsize проверяет размер окна после каждой команды и при необходимости обновляет значения переменных LINES и COLUMNS.

~/.bashrc
shopt -s checkwinsize

Оболочка завершается даже с опцией ignoreeof

После задания опции ignoreeof вы можете обнаружить, что многократное нажатие Ctrl-d всё равно приводит к завершению процесса оболочки. Дело в том, что по умолчанию эта опция позволяет игнорировать только 10 нажатий данной комбинации клавиш (если быть точным — 10 ситуаций EOF) перед выходом из оболочки.

Задать большее значение можно переменной IGNOREEOF. Например:

export IGNOREEOF=100

Анализ сценария и поиск ошибок

Программа shellcheck проверяет сценарии Bash (и других командных оболочек) на предмет ошибок и предлагает возможные улучшения кода.

Существует также веб-сайт shellcheck.net, разработанный на основе одноименной программы и предназначенный для той же цели.

Смотрите также

Обучение

Сообщество

Примеры