Переменные интепретатора bash
Привет, читателям моего блога. Недавно узнал многое о переменных в интерпретаторе 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
текущая установка локализации, которая позволяет настроить командную оболочку для использования в различных странах и на различных языках.
Место, где храниться почта
$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" $ cat 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 $ cat 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
Особые переменные (Позиционные переменные)
При вызове команды или сценария с аргументами, имя команды и ее аргументы являются позиционными переменными. Позиционными они называются, потому что внутри сценария обращение к ним происходит по позиции в командной строке. Давайте рассмотрим их на практике:
# Рассмотрим содержимое командного сценария $ cat 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
Хочу дополнить возможные действия над переменным: сдвиг и инициализация переменных. Опять же, проще будет понять данные действия на практике:
$ cat 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 выводится пустая строка, и правильно, потому что такой переменной нет. при заключении переменной в фигурные скобки – значение переменной объединяется с последующим текстом.
Резюме
На сегодня это все. Думаю представление о том, как работают переменные в bash, я изложил понятно. Желаю вам побольше практики!
Хочу сказать спасибо товарисчу – начальнику бога http://poplinux.ru/ за некоторые процитированные в статье примеры.
С Уважением, Mc.Sim!
Другие материалы в категории основы Linux
- Текстовый редактор VIM, основы работы
- ddrescue или спасаем данные с HDD
- Резервное копирование файлов сайта по ssh
- Седьмой релиз Debian
- Использование ramdisk в Linux (ramdisk, ramfs, tmpfs) или препарирование рамдисков
- SNMP протокол (основы)
- Установка антивирусного сканера ClamAV на Debian
- HOWTO использование backports в Debian
- Конспект установки Debian на сервер
- SSH сервер на Debian
Крутой блог, реально спасибо!!! ток вот тут лучше сделать так
server:~# var10=alex
server:~# echo $var10’ander’
У меня не пашит почему-то так как на Вашем примере
Спасибо.
и не должно пахать. потому что пример показывает, что будет выведена переменная $var10ander, которой несуществует, а вот echo ${var10}ander выведет значение переменной var10 и дополнит строкой ander.
Спасибо. Разжевано и уложено по нужным местам. У вас два образования? Преподаете?
Высшее – одно.
Преподавать – не преподаю )
#!/bin/bash
echo ScriptName is \>\>$0\<\< |wall
почему такой код, из крона (at -f script.sh now +1 MINUTE), вместо имени выведет sh
верно ли вставился код?
http://pastebin.com/Hmd2Dbrv
да, всё верно
http://pastebin.com/rj1ffpDY
Здравствуйте! такой вопрос: при написании скрипта возможно ли указать, чтобы переменной присваивалось то, что введет пользователь после появления определенного сообщения?аналог из командного файла Windows:
{set /p peremennaya= “vvedite znachenie peremennoy:”
echo %peremennaya%
}
результат:
{vvedite znachenie peremennoy:
}
Да, для этого используется read.
Пример:
#!/bin/bash
printf 'Какой Linux дистрибутив Вы знаете? '
read DISTR
case $DISTR in
ubuntu)
echo "Я тоже знаю Ubuntu! Эта система основана на Debian."
;;
centos|rhel)
echo "Эй! Это мой любимый серверный дистрибутив!"
;;
windows)
echo "Очень смешно..."
;;
*)
echo "Хмм, кажется я никогда не использовал этот дистрибутив."
;;
esac
всё правильно. Сорри.
AT запускает команды из файла, а не скрипт
Отлично.
Рад, что вопрос решен.