Bash

Перейти к: навигация, поиск
Icon-cleanup.png Эта статья требует внимания, поскольку она не следует стандартам руководства wiki.
Если Вы желаете помочь, пожалуйста, ознакомьтесь с принятыми стандартами. Если у Вас есть какие-либо вопросы, пожалуйста свяжитесь с нами, мы всегда готовы Вам помочь! :-)

Bash это командный процессор Unix написанный для проекта GNU. Его имя это акроним от Bourne-again shell — игра слов (Bourne again / born again) в Bourne shell (sh), который был ранее очень важным коммандным процессором. Bourne shell распространялся вместе с Unix Version 7, примерно в 1978. Оригинальный Bourne shell был написан Стефаном Борном, который работал исследователем в Bell Labs. Bash shell был написан в 1987 Брайном Фоксом . В 1990, Чет Рамей стал основным мейнтейнером. Bash это командный процессор по умолчанию во многих Linux системах.


Основные моменты синтаксиса Bash

Синтаксис команд Bash это надмножество синтаксиса команд Bourne shell. Окончательная спецификация синтаксиса команд Bash есть в Bash Reference Manual, распространяемом проектом GNU. Эта глава выдвигает на первый план некоторые из уникальных особенностей синтаксиса Bash.

Множество важных скриптов командного процессора Bourne могут выполняться без изменения в Bash, за исключением тех скриптов Bourne, которые ссылаются на специальные переменные Bourne или используют встроенные команды Bourne. Синтаксис команд Bash включает в себя идеи скопированные с Korn shell (ksh) и C shell (csh), такие как редактирование командной строки, история команд, стек директории, переменные $RANDOM и $PPID, и синтаксис замены команды POSIX : $(...). Когда Bash используется как интерактивный командный процессор, он поддерживает автозавершение имен программ, имен файлов, имен переменных и т.д., если пользователь нажимает кнопку TAB.

Синтаксис Bash содержит множество расширений, в которых нуждался Bourne shell. Некоторые из них приведены здесь.

Целочисленная математика

Главное ограничение Bourne shell это то, что он не может выполнять вычисления с целыми числами без порождения внешнего процесса. Bash может выполнять целочисленные вычисления внутри процесса используя команду ((...)) и синтаксис переменной $[...], как показано ниже:

VAR=55             # Устанавливаем переменную VAR, равной 55.
((VAR = VAR + 1))  # Прибавляем единицу к переменной VAR. Заметьте отсутствие знака '$'.
((++VAR))          # Другой способ прибавления единицы к VAR. Выполняет префиксный инкремент.
((VAR++))          # Другой способ прибавления единицы к VAR.  Выполняет постфиксный инкремент.
echo $[VAR * 22]   # Умножаем VAR на 22 и передаем результат команде.
echo $((VAR * 22)) # Другой способ сделать то же.

Команда ((...)) так же может использоваться в условных утверждениях, потому что её выходной параметр это 0 или 1, которые могут интерпретироваться как true или false:

if ((VAR == Y * 3 + X * 2))
then
        echo Yes
fi

((Z > 23)) && echo Yes

Команда ((...)) поддерживает следующие относительные операторы: '==', '!=', '>', '<', '>=', и '<='.

Bash не поддерживает вычисления внутри процесса с числами с плавающей точкой. Только командные процессоры Unix поддерживают эту возможность Korn Shell (версия 1993 года ) и zsh (начиная с версии 4.0).

Перенаправление I/O

Bash имеет индивидуальный синтаксис перенаправления , который не поддерживает Bourne shell. Bash может перенаправлять стандартный вывод и стандартные ошибки одновременно, используя следующий синтаксис:

command &> file

что проще напечатать, чем эквивалентную команду используя синтаксис Bourne shell "command > file 2>&1". Bash, начиная с версии 2.05b, может перенаправлять стандартный ввод из строки используя следующий синтаксис (иногда называемый "here strings"):

command <<< "string to be read as standard input"

Если строка содержит пробелы, она должна быть заключена в кавычки.

Пример: Перенаправление стандартного вывода в файл, запись данных, закрытие файла, сброс stdout

# make Filedescriptor(FD) 6 a copy of stdout (FD 1)
exec 6>&1
# open file "test.data" for writing
exec 1>test.data
# produce some content
echo "data:data:data"
# close file "test.data"
exec 1>&-
# make stdout a copy of FD 6 (reset stdout)
exec 1>&6
# close FD6
exec 6>&-

Открытие и закрытие файлов

# open file test.data for reading
exec 6<test.data
# read until end of file
while read -u 6 dta
do
  echo "$dta" 
done
# close file test.data
exec 6<&-

Захват вывода внешних команд:

 # execute 'find' and store results in VAR
 # search for filenames which end with the letter "h"
 VAR=$(find . -name "*h")

Регулярные вычисления внутри процесса

Bash 3.0 поддерживает внутри процессные регулярные вычисления соответствующие использованию следующего синтаксиса, напоминающего Perl:

[[ string =~ regex ]]

Синтаксис регулярных вычислений такой же что и задокументированный на страницах документации regex(3). Статус выхода вышеупомянутой команды 0 если перечисление regex это строка, 1 если это не так. К введенным подвыражениям в регулярном выражении можно получить доступ, используя переменную командного процессора BASH_REMATCH, как показано ниже:

if [[ abcfoobarbletch =~ 'foo(bar)bl(.*)' ]]
then
        echo The regex matches!
        echo $BASH_REMATCH      -- outputs: foobarbletch
        echo ${BASH_REMATCH[1]} -- outputs: bar
        echo ${BASH_REMATCH[2]} -- outputs: etch
fi

Этот синтаксис дает лучшее выполнение порождения отдельного процесса чтобы выполнить команду grep, потому что соответствующее регулярное выражение имеет место в пределах процесса Bash. Если регулярное выражение или строка содержат пробелы или метасимволы (такие как '*' or '?'), они должны быть помещены в кавычки.

Обратные escape последовательности

Слова, имеющие форму $'строка' рассматриваются отдельно. Слово расширяется до строки, с помощью символов обратных escape последовательностей, описанных в языке программирования C. Обратные escape последовательности, если присуствуют, декодируются как показано ниже:

Обратные Escape последовательности
Backslash
Escape
Expands To ...
\a Символ звукового сигнала
\b Символ backspace
\e Символ escape
\f Символ подачи формы
\n Символ новой строки
\r Символ перевода каретки
\t Символ горизонтальной табуляции
\v Символ вертикальной табуляции
\\ Символ обратного слеша
\' Символ одинарной кавычки
\nnn Восьмибитный символ , значение которого - восьмеричное значение nnn (one to three digits)
\xHH Восьмибитный символ , значение которого - шестнадцатиричное чило HH (one or two hex digits)
\cx Символ control-X

Расширенный результат записан в одинарных кавычках, как будто знак доллара не был указан.

Строка в двойных кавычках, которой предшествует знак доллара ($"...") заставит строку быть переведенной согласно текущему месту действия. Если текущее место действие это C или POSIX, знак доллара игнорируется. Если строка переведена и заменена, указываются двойные кавычки.

Стартовые скрипты Bash

Когда запускается Bash, он выполняет команды, записанные в разнообразных скриптах.

Когда Bash вызывается интерактивной командной оболочкой, либо неинтерактивной оболочкой с параметром --login, он сначала читает и выполняет команды из файла /etc/profile, если он существует. После прочтения этого файла, он в таком порядке ищет ~/.bash_profile, ~/.bash_login, и ~/.profile, читает и выполняет команды из первого, который выполняется и читается. Параметр --noprofile может использоваться, когда командная оболочка препятствует такому поведению.

Когда командная оболочка завершает свою работу, Bash читает и выполняет команды из файла ~/.bash_logout, если он существует.

Когда интерактивная оболочка, не являющаяся командной оболочкой, запускается, Bash читает и выполняет команды из ~/.bashrc, если этот файл существует. Это может быть замедлено параметром --norc. Параметр --rcfile file заставит Bash читать и выполнять каманды из file вместо ~/.bashrc.

Когда Bash запускается неинтерактивно, то для запуска скрипта оболочки, например, он ищет переменную BASH_ENV в среде, расширяет свое значение если он появится там, и использует расширенное значение как имя файла для чтения и выполнения. Bash ведет себя как если бы были выполнены следующие команды:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

но значение переменной PATH не используется для поиска файла.

Если Bash вызывается с параметром sh, он пытается имитировать запуск исторических комманд sh на сколько это возможно, в то время как соответствующий стандарт POSIX так же. Если Bash запущено в качестве интерактивной оболочки, или в форме не интерактивной с --login опцией, это первая попытка на чтение и выполнение команд с /etc/profile и ~/.profile, в таком порядке. Эта --noprofile опция может быть использована для ингибиции. При вызове в качестве интерактивной оболочки с именем sh, Bash смотрит на переменные ENV, на ихнее значение, если переменная определена, и использует расширенное значение как имя файла для записи и выполнения. Пока shell вызывается как sh, то параметр --rcfile не даёт результата. Не интерактивная оболочка вызвана с параметром sh не пытается читать и выполнять команды от любых других файлов запуска. Когда вызвана с sh, Bash входит в posix mode после автозапуска готовых файлов.

Когда Bash запущена в POSIX-режиме, с параметром --posix в командной строке, Это следует POSIX-стандарту для файлов автозапуска. В этом режиме, оболочка дополняется ENV переменной и командами, которые готовы для выполнения с файла, чьё имя и есть эта переменная.

Bash пытается определить когда она будет запущена на remote shell daemon, обычно это rshd. Если Bash опредилит, что оболочка в настоящее время запущена rshd, то читаются и выполняются комманды с ~/.bashrc, если этот файл доступен конечно. Это не произойдет если Bash вызвана с sh. Опция --norc может быть использована для ингибинации такого поведения, и опция --rcfile может быть задействована для записи другого файла, но rshd как правило, не ссылается на оболочку с этими опциями, или чтобы их можно было указать.

Дополнительные ссылки

Руководства по Bash из Linux Documentation Project:

Другие руководства и учебники: