Переменные в интерпретаторе bash.

variable bashrc var bash

Переменные в bash очень интенсивно используются при написании скриптов, как впрочем, и в любом языке программирования для написания программ. Типы переменных в bash отсутствуют. Переменная в bash может представлять собой число, символ или строку символов. Имя переменной может начинаться с буквы или с символа подчеркивания и не может содержать дефис.Физически, переменные представляют собой именованные участки памяти, в которые может быть записана какая-либо информация. Необходимо понимать различия между именем переменной и ее значением. Если var1 — это имя переменной, то $var1 — это ссылка на ее значение.

Хотя, вышесказанное об отсутствии типа переменной можно оспорить, ибо переменные в bash делятся на Ключевые переменные (их же называю еще - глобальными, стандартными, переменные среды или внутренними) и пользовательские (которые определены пользователем во время работы). При этом, пользователь может переводит свою пользовательскую переменную в глобальную, с помощью команды export. Об остальных командах управления переменным можно почитать тут.

При использовании переменных, существует такое негласное соглашение, упрощающее работу: для глобальных переменных используются только ПРОПИСНЫЕ буквы, для остальных - строчные.

Переменные среды

Данные переменные, заданы в файлах /etc/.profile, ~/.profile, ~/.bashrc, ~/.bash_profile и инициализируются при загрузке, либо при выполнении команды “. .файл_инициализации”. Обычно, основные значения переменных среды следующие:

$BASH
В переменной $BASH содержится полный путь до исполняемого файла командной оболочки Bash.

$BASH_VERSION
В переменную $BASH_VERSION записывается версия Bash.
$CDPATH

Переменная, которая хранит пути поиска каталога. (используется при вводе команды cd имя_каталога без слэша)

$CLASSPATH
содержит список каталогов для поиска файлов классов Java и архивов Java.
$HOME
домашний каталог текущего пользователя.
$HOSTNAME
В переменной $HOSTNAME хранится имя компьютера.
$HISTSIZE
количество событий, хранимых в истории за 1 сеанс
$HISTFILE
Расположение файла истории событий
$HISTFILESIZE
количество событий, хранимых в истории между сеансами
$IFS
переменная хранит символы, являющиеся разделителями команд и параметров. (по умолчанию - пробел, табуляция и новая строка)
$LANG
текущая установка локализации, которая позволяет настроить командную оболочку для использования в различных странах и на различных языках.
$MAIL
Место, где храниться почта
$OSTYPE
В переменной $OSTYPE содержится описание операционной системы.
$PATH
список каталогов для поиска команд и приложений, когда полный путь к файлу не задан.
$PS1
PS1 используется как основная строка приглашения. (то самое [root@proxy ~]#)
$PS2
PS2 используется как вторичная строка приглашения.
$PROMPT_COMMAND
Эта команда должна быть выполнена до отображения строки приглашения Bash.
$PWD
полный путь к текущему рабочему каталогу.
$SHELL
полный путь к текущей командной оболочке.
$USER
В переменной $USER содержится имя текущего пользователя.

Переменные пользователя

Присвоение значения переменной

Пользовательские переменные появляются, как только пользователь “объявит” данную переменную, то есть присвоит переменной какое-то значение:

$ var="123   345"       # Присваивание значения переменной
# Если в значениях переменных встречаются пробелы,
# то использование кавычек обязательно, иначе - можно без кавычек.
$ variable=$var         # Подстановка значения переменной
#-------------------------------------------------------------------------
# Использование пробельных символов
#  с обеих сторон символа "=" присваивания недопустимо.
# Если записать "VARIABLE =value",
#  то интерпретатор попытается выполнить команду "VARIABLE" с параметром "=value".
# Если записать "VARIABLE= value",
#  то интерпретатор попытается установить переменную окружения "VARIABLE" в ""
#  и выполнить команду "value".
#-------------------------------------------------------------------------
$ echo var              # Это НЕ вывод переменной
var
$ echo $var
123 345
$ echo $variable
123 345
$ echo "$variable"
123   345
# Как видно, использование кавычек при выводе значения переменной сохраняет
# пробельные символы в переменной
$ echo '$variable'
$variable
$ echo $variable
$variable
# Внутри одинарных кавычек не производится подстановка значений переменных,
#  т.е. "$" интерпретируется как простой символ. А так же при использовании
#  символа экранирования.
$ variable=            # Запись пустого значения в переменную(!но не удаление)
$ echo $variable
#  Обратите внимание: запись пустого значения — это не то же самое,
#   что сброс переменной, хотя конечный результат — тот же (см. ниже).
$ echo "uninitialized_variable = $uninitialized_variable"
uninitialized_variable = #пустое
# Неинициализированная переменная содержит "пустое" значение.
$ unset uninitialized_variable    # Сброс переменной.
$ echo "uninitialized_variable = $uninitialized_variable"
uninitialized_variable = #пустое

Действия над переменными

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

$ readonly variable    # пометка переменной "только для чтения"
$ variable=789
-bash: variable: доступная только на чтение переменная
$ cat test             #содержимое первого скрипта

#! /bin/bash
variable1=znachenie    #объявление переменной
echo "test 1: $variable1"      #вывод переменной
./subtest              #запуск вложенного скрипта
echo "test 2: $variable1"           #вывод переменной после запуска вложенного скрипта
export variable1       #экспорт переменной
echo "test 3: $variable1"
./subtest
echo "test 4: $variable1"
содержимое скрипта subtest, запускаемого из первого

#! /bin/bash
echo "subtest 1: $variable1"
variable1=drugoe
echo "subtest 2: $variable1"
$ ./test 

test 1: znachenie
subtest 1:
subtest 2: drugoe
test 2: znachenie
test 3: znachenie
subtest 1: znachenie
subtest 2: drugoe
test 4: znachenie

Листинг where

where=$(pwd)
echo "Вы работаете в каталоге 1: $where"
echo "Вы работаете в каталоге 2: $(pwd)"
where2=`pwd`
echo "Вы работаете в каталоге 3: $where2"
# Как видно, переменной можно присвоить значение вывода какой-либо команды
# используя комбинацию $(command) или `command` (апострофы).
$ ./where

Вы работаете в каталоге 1:  /home/user
Вы работаете в каталоге 2:  /home/user
Вы работаете в каталоге 3: /home/user

Особые переменные (Позиционные переменные)

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

Рассмотрим содержимое командного сценария display_arg

#! /bin/bash
echo "Имя запущенного сценария: $0"
echo "Первые пять аргументов командной строки: $1 $2 $3 $4 $5"
echo "Всего аргументов сценария: $#"
echo "Все аргументы у запущенного сценария: $*"
echo "Если аргументов более 10, то выводим 10 так: ${10}"
echo "PID запущенного сценария: $$"
sleep 5 &
echo "PID последнего процесса, запущенного в фоне: $!"
ls display_
echo "Команда ls display_ завершилась статусом: $?"
ls display_arg
echo "Команда ls display_arg завершилась статусом: $?"

Запустим сценарий

$ ./display_arg 1 98 kjk 98 njk88 kjkj 78 kjkj66 jkj k l h

Вывод команды:

Имя запущенного сценария: ./display_arg
Первые пять аргументов командной строки: 1 98 kjk 98 njk88
Всего аргументов сценария: 12
Все аргументы у запущенного сценария: 1 98 kjk 98 njk88 kjkj 78 kjkj66 jkj k l h
Если аргументов более 10, то выводим 10 так: k
PID запущенного сценария: 3316
PID последнего процесса, запущенного в фоне: 3317
ls: невозможно получить доступ к display_: Нет такого файла или каталога
Команда ls display_ завершилась статусом: 2
display_arg
Команда ls display_arg завершилась статусом: 0

Из приведенного скрипта видно, что:

  • $0 - хранит имя команды, запустившей сценарий
  • 1-n - переменные хранят 1, 2, 3,…n позицию аргументов команды
  • $# - хранит количество аргументов команды
  • $* - хранит значение всех аргументов командной строки через пробел
  • $@ - хранит значение всех аргументов командной строки в виде списка
  • $$ - хранит PID запущенного сценария (процесса)
  • $! - хранит значение PID последнего процесса, запущенного в фоне
  • $? - Статус выхода запущенной последней программы. Он так же называется кодом условия, кодом возврата. По соглашению, ненулевое значение статусы завершения соответствует значению false и обозначает неудачное завершение процесса. Код выхода равный 0 соответствует true и обозначает успешное завершение программы. в нашем примере ls display_ завершилось с ошибкой и кодом выхода 2, т.к. файла или каталога display_ не существует.

Действия над переменными 2

Хочу дополнить возможные действия над переменным: сдвиг и инициализация переменных. Опять же, проще будет понять данные действия на практике:

Листинг set_shift

#! /bin/bash
echo "var1=$1   var2=$2         var3=$3"
shift
echo "var1=$1   var2=$2         var3=$3"
shift
echo "var1=$1   var2=$2         var3=$3"
shift
echo "var1=$1   var2=$2         var3=$3"
echo "Посмотрим как присваиваются переменные командой set"
set как это присваивается
echo "Вот $1 $3 $2"
Запускаем:

$ ./set_shift mama papa dom
var1=mama       var2=papa               var3=dom
var1=papa       var2=dom                var3=
var1=dom        var2=           var3=
var1=   var2=           var3=

Посмотрим как присваиваются переменные командой set

Вот как присваивается это

Как видно, команда shift “сдвигает” позиционные параметры, в результате чего параметры “сдвигаются” на одну позицию влево.

X <- $1, $1 <- $2, $2 <- $3, $3 <- $4, и т.д.
Прежний аргумент $1 теряется, но аргумент $0 (имя файла сценария) остается без изменений.

Команда set устанавливает позиционные переменные на основе переданных ей аргументов, разделенных пробелами. Соответственно, команде set возможно передать в виде аргументов и вывод какой-либо команды в виде set $(command). Параметры команды set можно посмотреть тут.

P.S. Кроме использования ссылки на переменную в формате $имя_переменной, возможен и такой синтаксис: ${имя_переменной}. Данный синтаксис позволяет объединить переменную с другим текстом.

Пример:

server:~# var10=alex
server:~# echo $var10ander
server:~# echo ${var10}ander
alexander

Как видно в примере, при попытке вывести значение переменной $var10ander выводится пустая строка, и правильно, потому что такой переменной нет. при заключении переменной в фигурные скобки - значение переменной объединяется с последующим текстом.