Наши партнеры








Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Электронные книги по ОС Linux
Руководство по Bash для начинающих
Назад Глава 3: Среда окружения Bash Вперед

Переменные

Типы переменных

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

Глобальные переменные

Глобальные переменные или переменные среды окружения доступны во всех оболочках. Чтобы показать переменные среды окружения, можно использовать команды env или printenv. Эти команды поставляются в составе пакета sh-utils.

Ниже показан типичный результат выдачи:

Локальные переменные

Локальные переменные доступны только в текущей командной оболочке. Если встроенная команда set используется без каких-либо параметров, то она выдаст список всех переменных (в том числе переменные среды исполнения) и функций. Воспользуемся форматированием и выдадим отсортированный результат, учитывающий локальность переменных.

Ниже приведен файл diff, созданный путем сравнения результата работы команд printenv и set, после удаления из списка функций, которые также отображаются командой set:

franky ~> diff set.sorted printenv.sorted | grep "<" | awk '{ print $2 }'
BASE=/nethome/franky/.Shell/hq.garrels.be/octarine.aliases
BASH=/bin/bash
BASH_VERSINFO=([0]="2"
BASH_VERSION='2.05b.0(1)-release'
COLUMNS=80
DIRSTACK=()
DO_FORTUNE=
EUID=504
GROUPS=()
HERE=/home/franky
HISTFILE=/nethome/franky/.bash_history
HOSTTYPE=i686
IFS=$'
LINES=24
MACHTYPE=i686-pc-linux-gnu
OPTERR=1
OPTIND=1
OSTYPE=linux-gnu
PIPESTATUS=([0]="0")
PPID=10099
PS4='+
PWD_REAL='pwd
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
THERE=/home/franky
UID=504
Awk

Язык программирования GNU Awk объясняется в главе 6 "Язык программирования GNU Awk".

Деление переменных по их содержимому

Помимо деления переменных на локальные и глобальные, мы можем также разделить их на категории в зависимости от того, какое содержимое хранится в переменной. В этом отношении переменные подразделяются на четыре типа:

  • Строковые переменные
  • Целочисленные переменные
  • Переменные - константы
  • Переменные - массивы

Мы обсудим эти типы переменных в главе 10 "Подробнее о переменных". Сейчас мы будем использовать в наших переменных целочисленные и строковые значения.

Создание переменных

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

prompt> export 1number=1
bash: export: `1number=1': not a valid identifier

Чтобы в командной оболочке задать переменную, используйте следующую команду

VARNAME="value"

Вокруг знака равенства не следует вставлять пробелы — это приведет к ошибкам. Когда вы назначаете значения переменным, то хорошей привычкой является заключение содержимого строки в кавычки; это уменьшает шанс того, что вы сделаете ошибку.

Некоторые примеры использования верхнего и нижнего регистров, цифр и пробелов (сообщение command not found указывает на наличие проблемы — прим.пер.):

franky ~> MYVAR1="2"

franky ~> echo $MYVAR1
2

franky ~> first_name="Franky"

franky ~> echo $first_name
Franky

franky ~> full_name="Franky M. Singh"

franky ~> echo $full_name
Franky M. Singh

franky ~> MYVAR-2="2"
bash: MYVAR-2=2: command not found

franky ~> MYVAR1 ="2"
bash: MYVAR1: command not found

franky ~> MYVAR1= "2"
bash: 2: command not found

franky ~> unset MYVAR1 first_name full_name

franky ~> echo $MYVAR1 $first_name $full_name
<--no output-->

franky ~>

Экспорт переменных

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

export VARNAME="value" 

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

franky ~> full_name="Franky M. Singh"

franky ~> bash

franky ~> echo $full_name


franky ~> exit

franky ~> export full_name

franky ~> bash

franky ~> echo $full_name
Franky M. Singh

franky ~> export full_name="Charles the Great"

franky ~> echo $full_name
Charles the Great

franky ~> exit

franky ~> echo $full_name
Franky M. Singh

franky ~>

Когда в подоболочке первый раз делается попытка прочитать значение full_name, это значение не установлено (команда echo показывает пустую строку). После того, как происходит выход из подоболочки, переменная full_name экспортируется в родительскую оболочку - переменная может экспортироваться после того, как ей было присвоено значение. Затем запускается новая подоболочка, в которой будет видна переменная, экспортированная из родительской оболочки. Переменная изменяется и в ней будет запомнено другое значение, но в родительской оболочке значение этой переменной остается прежним.

Зарезервированные переменные

Зарезервированные переменные командной оболочки Bourne

В Bash используются определенные переменные командной оболочки, точно такие же, как в оболочке Bourne. В некоторых случаях, Bash назначает переменной значение, задаваемое по умолчанию. В таблице ниже приводится краткое описание этих простых переменных командной оболочки:

Таблица 3.1. Зарезервированные переменные командной оболочки Bourne

Имя переменнойОпределение

CDPATH

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

HOME

Домашний директорий текущего пользователя; используется по умолчанию во встроенной команде cd. Значение этой переменной используется также вместо символа "тильда".

IFS

Список символов, с помощью которых разделяются поля; используется, когда оболочка после выполнения всех замен разделяет результат на отдельные слова.

MAIL

Если в этом параметре задано имя файла, а значение переменной MAILPATH не установлено, Bash проинформирует пользователя о получении письма в указанном файле.

MAILPATH

Список имен файлов, разделенных двоеточиями, которые командная оболочка периодически проверяется на наличие новых писем.

OPTARG

Значение последнего аргумента в параметре, обработанного встроенной командой getopts.

OPTIND

Индекс последнего аргумента параметра, обработанного встроенной командой getopts.

PATH

Список директориев, разделенных двоеточиями, в которых командная оболочка ищет команды.

PS1

Первичная строка приглашения. Значение по умолчанию равно "'\s-\v\$ '".

PS2

Вторичная строка приглашения. Значение по умолчанию равно "'> '".

Зарезервированные переменные Bash

Значения этих переменных задаются или используются в Bash, но в других командных оболочках они обычно не рассматриваются как специальные.

Таблица 3.2. Зарезервированные переменные Bash

Имя переменнойОпределение

auto_resume

Эта переменная управляет тем, как оболочка взаимодействует с пользователем и выполняет задания.

BASH

Полный путь, используется для запуска текущего экземпляра Bash.

BASH_ENV

Если эта переменная задана в тот момент, когда Bash вызывается для выполнения скрипта, ее значение используется в качестве имени файла запуска, который должен быть прочитан перед выполнением скрипта.

BASH_VERSION

Номер версии текущего экземпляра Bash.

BASH_VERSINFO

Переменная — массив, используемая только для чтения, в элементах массива которой хранится информация, касающаяся версии данного экземпляра Bash.

COLUMNS

Когда происходит печать выбранных списков, используется встроенной командой select для определения ширины терминала. Автоматически устанавливается при получении сигнала SIGWINCH.

COMP_CWORD

Указатель в ${COMP_WORDS} для слова, в котором хранится текущая позиция курсора.

COMP_LINE

Текущая командная строка.

COMP_POINT

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

COMP_WORDS

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

COMPREPLY

Переменная - массив, из которого Bash считывает возможные варианты завершения строки, сгенерированные функцией командной оболочки, вызванной сервисом, предназначенным для программирования завершений

IRSTACK

Переменная — массив, в которой хранится текущее состояние стека директориев.

EUID

Числовой действующий идентификатор пользователя ID текущего пользователя.

FCEDIT

Редактор, используемый по умолчанию, когда во во встроенной команде fc указывается параметр -e

GNORE

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

FUNCNAME

Имя функции командной оболочки, исполняемой в текущий момент.

GLOBIGNORE

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

GROUPS

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

histchars

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

HISTCMD

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

HISTCONTROL

Определяет, будет ли команда добавляться в файл истории команд.

HISTFILE

Имя файла, в котором сохраняется история команд. Значение по умолчанию: ~/.bash_history.

HISTFILESIZE

Максимальное количество строк, содержащихся в файле истории команд, по умолчанию - 500.

HISTIGNORE

Список шаблонов, разделенных двоеточиями, с помощью которых определяется, должна ли команда сохраняться в списки истории команд.

HISTSIZE

Максимальное количество команд, которое можно запомнить в списке истории команд, по умолчанию - 500.

HOSTFILE

Содержит имя файла в том же формате, что и файл /etc/hosts, которое может быть прочитано, когда командной оболочке требуется завершить имя хоста.

HOSTNAME

Имя текущего хоста.

HOSTTYPE

Строка, описывающая машину, на которой работает Bash.

IGNOREEOF

Управляет действием командной оболочки при получении ею в качестве завершающего символа входного потока символа EOF (символ конца файла).

INPUTRC

Имя файла инициализации программы Readline, которым заменяется файл /etc/inputrc, использумый по умолчанию.

LANG

Используется для определения категории локализации (locale) для всех категорий, не заданных явно с помощью переменных, имена которых начинаются с символов LC_.

LC_ALL

Эта переменная переопределяет значение переменной LANG и всех остальных переменных, начинающихся с символов LC_, задающих категорию локализации.

LC_COLLATE

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

LC_CTYPE

Эта переменная определяет интерпретацию символов и принадлежность символов к определенному классу для подстановки имен файлов и сопоставления с шаблоном.

LC_MESSAGES

Эта переменная определяет категорию локализации, используемую для обработки строк в двойных кавычках, перед которыми указан символ $.

LC_NUMERIC

Эта переменная определяет категорию локализации для числового формата.

LINENO

Номер строки в скрипте или в функции оболочки, которая исполняется в текущий момент.

LINES

Используется встроенной командой select для определения длины столбца, в который выводятся выбранные списки.

MACHTYPE

Строка, которая полностью описывает тип системы, на которой выполняется Bash, используется стандартный формат GNU CPU-COMPANY-SYSTEM.

MAILCHECK

Определяет (в секундах) как часто командная оболочка должна проверять почту в файлах, указанные в переменных MAILPATH или MAIL.

OLDPWD

Предыдущий рабочий директорий, установленный с помощью встроенной команды cd.

OPTERR

Если установлено значение 1, то Bash отображает сообщения об ошибках, генерируемые встроенной командой getopts.

OSTYPE

Строка, описывающая операционную систему, на которой работает Bash.

PIPESTATUS

Переменная - массив, содержащая список значений состояний выхода из процессов в последнем конвейере (который может состоять из одной команды).

POSIXLY_CORRECT

Если эта переменная добавлена в окружающую среду при запуске bash, командная оболочка переходит в режим POSIX.

PROMPT_COMMAND

Если эта переменная установлена, то значение интерпретируется как команда, которая выполняется перед каждой выдачей первичной строки приглашения (PS1).

PS3

Значение этой переменной используется для команды select в качестве строки приглашения. По умолчанию - "'#? '"

PS4

Значение строки приглашения, которое выдается перед командной строкой, когда установлен параметр -x, включающий эхо-выдачу командной строки; по умолчанию - "'+ '".

PWD

Текущий рабочий директорий, установленный встроенной командой cd.

RANDOM

Каждый раз, когда происходит обращение к этому параметру, генерируется случайное целое число в диапазоне от 0 до 32767. Значение этой переменной используется в генераторах случайных чисел.

REPLY

Переменная, используемая по умолчанию во встроенной команде read.

SECONDS

В этой переменной указывается количество секунд, прошедших с момента запуска командной оболочки.

SHELLOPTS

Список параметров, установленных в командной оболочке; разделены двоеточиями.

SHLVL

Увеличивается на единицу каждый раз, когда запускается новый экземпляр Bash.

TIMEFORMAT

Значение этого параметра используется в качестве строки, задающей формат выдачи информации о времени выполнения для конвейеров, перед которыми задано зарезервированное слово time.

TMOUT

Если в переменной TMOUT установлено значение больше нуля, то оно рассматривается как время ожидания, используемое по умолчанию во встроенной команде read. Когда командная оболочка запускается в интерактивном режиме, это значение интерпретируется как количество секунд, которое оболочка будет ждать ввод после выдачи первичной строки приглашения. В случае, если входные данные не поступают, то по истечению этого времени Bash завершает свою работу.

UID

Числовое значение, реальный идентификатор пользователя ID для текущего пользователя.

Дополнительную информацию смотрите на страницах man по Bash или в документации. Некоторые переменные доступны только для чтения, значение некоторых устанавливается автоматически, а некоторые теряют свой смысл, когда для них устанавливается значение, отличающееся от значения, задаваемого по умолчанию.

Специальные параметры

Командная оболочка рассматривает некоторые параметры специальным образом. Эти параметры можно использовать только для получения из них значений, назначать им значения нельзя.

Таблица 3.3. Специальные переменные bash

СимволОпределение

$*

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

$@

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

$#

Возвращает количество позиционных параметров, указываемых в виде десятичного значения.

$?

Возвращает код возврата последнего конвейера, выполненном в приоритетном режиме (в режиме foreground — прим.пер.).

$-

С помощью параметра "дефис" возвращаются флаги текущего параметра в том виде, как они были установлены при вызове встроенной команды set, или так, как они были установлены самой командной оболочкой (например, -i).

$$

Возвращает идентификатор процесса командной оболочки.

$!

Возвращает идентификатор процесса последней команды, выполненной в фоновом (асинхронном) режиме.

$0

Возвращает имя командной оболочки или скрипта.

$_

Значение параметра "подчеркивание" устанавливается при запуске командной оболочки и содержит полное имя командной оболочки или скрипта, которые выполняется в том виде, как он был передан в списке аргументов. Затем значение будет заменено последним аргументом предыдущей команды. В этом параметре также указывается полный путь к каждой команде, выполненной и помещенной в среду, которая была экспортирована в эту команду. Когда проверяется почта, в этом параметре содержится имя почтового файла.

Параметр $* или параметр $@

Реализация параметра “$*” всегда была проблемой и, в действительности, должна быть заменена реализацией параметра “$@”. Почти в каждом случае, когда программисты используют параметр “$*”, предполагается, что им нужно значение “$@”. Параметр “$*” может стать причиной ошибок и даже дыр безопасности в вашем программном обеспечении.

Позиционные параметры являются словами, следующими за именем скрипта командной оболочки. Они запоминаются в переменных $1, $2, $3 и так далее. Переменные, по мере необходимости, добавляются во внутренний массив. В переменной $# указывается общее число параметров, так как это продемонстрировано в следующем простом скрипте:

# positional.sh
# This script reads 3 positional parameters and prints them out.

POSPAR1="$1"
POSPAR2="$2"
POSPAR3="$3"

echo "$1 is the first positional parameter, \$1."
echo "$2 is the second positional parameter, \$2."
echo "$3 is the third positional parameter, \$3."
echo
echo "The total number of positional parameters is $#."

При запуске скрипта можно указывать любое число аргументов:

franky ~> positional.sh one two three four five
one is the first positional parameter, $1.
two is the second positional parameter, $2.
three is the third positional parameter, $3.

The total number of positional parameters is 5.

franky ~> positional.sh one two
one is the first positional parameter, $1.
two is the second positional parameter, $2.
 is the third positional parameter, $3.

The total number of positional parameters is 2.

Подробнее об использовании этих параметров рассказывается в главе 7 "Условные инструкции" и в разделе "Встроенная команда shift".

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

franky ~> grep dictionary /usr/share/dict/words
dictionary

franky ~> echo $_
/usr/share/dict/words

franky ~> echo $$
10662

franky ~> mozilla &
[1] 11064

franky ~> echo $!
11064

franky ~> echo $0
bash

franky ~> echo $?
0

franky ~> ls doesnotexist
ls: doesnotexist: No such file or directory

franky ~> echo $?
1

franky ~>

Пользователь franky начинает с ввода команды grep, в результате чего назначается значение переменной _. Идентификатор процесса этой оболочки равен 10662. Если выполнение какого-то задания переводится в фоновый режим, в переменной ! будет находиться идентификатор процесса фонового задания. Работающей командной оболочкой является bash. Если была допущена ошибка, в переменной ? будет находиться код возврата, отличающийся от 0 (нуля).

Расширение сферы применения скриптов, имеющих переменные

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

#!/bin/bash

# This script makes a backup of my home directory.

cd /home

# This creates the archive
tar cf /var/tmp/home_franky.tar franky > /dev/null 2>&1

# First remove the old bzip2 file.  Redirect errors because this generates some if the archive
# does not exist.  Then create a new compressed file.
rm /var/tmp/home_franky.tar.bz2 2> /dev/null
bzip2 /var/tmp/home_franky.tar

# Copy the file to another host - we have ssh keys for making this work without intervention.
scp /var/tmp/home_franky.tar.bz2 bordeaux:/opt/backup/franky > /dev/null 2>&1

# Create a timestamp in a logfile.
date >> /home/franky/log/home_backup.log
echo backup succeeded >> /home/franky/log/home_backup.log

Прежде всего, у вас больше шансов сделать ошибки, если вы будет вручную задавать файлы и директории всякий раз, когда они вам понадобятся. Во-вторых, предположим, что пользователь franky хочет передать этот скрипт пользователю carol, тогда прежде, чем carol сможет использовать скрипт для резервного копирования своего домашнего директория, ему придется довольно много редактировать. То же самое случится, если пользователь franky захочет использовать этот скрипт для резервного копирования других директориев. Чтобы расширить сферу применения, используйте переменные для всех файлов, директориев, имен пользователей, имен серверов и т.д. Тогда вам потребуется изменить значение всего лишь один раз и не просматривать весь скрипт с тем, чтобы найти все места, где встречается конкретный параметр. Пример:

#!/bin/bash
                                                                                                 
# This script makes a backup of my home directory.

# Change the values of the variables to make the script work for you:
BACKUPDIR=/home
BACKUPFILES=franky
TARFILE=/var/tmp/home_franky.tar
BZIPFILE=/var/tmp/home_franky.tar.bz2
SERVER=bordeaux
REMOTEDIR=/opt/backup/franky
LOGFILE=/home/franky/log/home_backup.log

cd $BACKUPDIR

# This creates the archive
tar cf $TARFILE $BACKUPFILES > /dev/null 2>&1
                                                                                                 
# First remove the old bzip2 file.  Redirect errors because this generates some if the archive 
# does not exist.  Then create a new compressed file.
rm $BZIPFILE 2> /dev/null
bzip2 $TARFILE

# Copy the file to another host - we have ssh keys for making this work without intervention.
scp $BZIPFILE $SERVER:$REMOTEDIR > /dev/null 2>&1

# Create a timestamp in a logfile.
date >> $LOGFILE
echo backup succeeded >> $LOGFILE
Большие директории и низкая пропускная способность

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


Предыдущий раздел: Оглавление Следующий раздел:
Файлы инициализации командной оболочки   Символы кавычек