Мендель Купер - Искусство программирования на языке сценариев командной оболочки
Пример 8-4. Различные представления числовых констант
#!/bin/bash
# numbers.sh: Различные представления числовых констант.
# Десятичное: по-умолчанию
let "dec = 32"
echo "десятичное число = $dec" # 32
# Вобщем-то ничего необычного.
# Восьмеричное: числа начинаются с '0' (нуля)
let "oct = 032"
echo "восьмеричное число = $oct" # 26
# Результат печатается в десятичном виде.
# --------- ------ -- -------
# Шестнадцатиричное: числа начинаются с '0x' или '0X'
let "hex = 0x32"
echo "шестнадцатиричное число = $hex" # 50
# Результат печатается в десятичном виде.
# Другие основы счисления: ОСНОВА#ЧИСЛО
# ОСНОВА должна быть между 2 и 64.
# для записи ЧИСЛА должен использоваться соответствующий ОСНОВЕ диапазон символов,
# см. ниже.
let "bin = 2#111100111001101"
echo "двоичное число = $bin" # 31181
let "b32 = 32#77"
echo "32-ричное число = $b32" # 231
let "b64 = 64#@_"
echo "64-ричное число = $b64" # 4094
#
# Нотация ОСНОВА#ЧИСЛО может использоваться на ограниченном
#+ диапазоне основ счисления (от 2 до 64)
# 10 цифр + 26 символов в нижнем регистре + 26 символов в верхнем регистре + @ + _
echo
echo $((36#zz)) $((2#10101010)) $((16#AF16)) $((53#1aA))
# 1295 170 44822 3375
# Важное замечание:
# --------------
# Использование символов, для записи числа, выходящих за диапазо,
#+ соответствующий ОСНОВЕ счисления
#+ будет приводить к появлению сообщений об ошибках.
let "bad_oct = 081"
# numbers.sh: let: oct = 081: value too great for base (error token is "081")
# Для записи восьмеричных чисел допускается использовать
#+ только цифры в диапазоне 0 - 7.
exit 0 # Спасибо Rich Bartell и Stephane Chazelas, за разъяснения.
Часть 3. Углубленный материал
Глава 9. К вопросу о переменных
Правильное использование переменных может придать сценариям дополнительную мощь и гибкость, а для этого необходимо изучить все тонкости и нюансы.
9.1. Внутренние переменные
Встроенные переменные $BASH
путь к исполняемому файлу Bash
bash$ echo $BASH
/bin/bash
$BASH_VERSINFO[n]
это массив, состоящий из 6 элементов, и содержащий информацию о версии Bash. Очень похожа на переменную $BASH_VERSION, описываемую ниже.
# Информация о версии Bash:
for n in 0 1 2 3 4 5
do
echo "BASH_VERSINFO[$n] = ${BASH_VERSINFO[$n]}"
done
# BASH_VERSINFO[0] = 2 # Major version no.
# BASH_VERSINFO[1] = 05 # Minor version no.
# BASH_VERSINFO[2] = 8 # Patch level.
# BASH_VERSINFO[3] = 1 # Build version.
# BASH_VERSINFO[4] = release # Release status.
# BASH_VERSINFO[5] = i386-redhat-linux-gnu # Architecture
# (same as $MACHTYPE).
$BASH_VERSION
версия Bash, установленного в системе
bash$ echo $BASH_VERSION
2.04.12(1)-release
tcsh% echo $BASH_VERSION
BASH_VERSION: Undefined variable.
Проверка переменной $BASH_VERSION -- неплохой метод проверки типа командной оболочки, под которой исполняется скрипт. Переменная $SHELL не всегда дает правильный ответ.
$DIRSTACK
содержимое вершины стека каталогов (который управляется командами pushd и popd)
Эта переменная соответствует команде dirs, за исключением того, что dirs показывает полное содержимое всего стека каталогов.
$EDITOR
заданный по-умолчанию редактор, вызываемый скриптом, обычно vi или emacs.
$EUID
"эффективный" идентификационный номер пользователя (Effective User ID)
Идентификационный номер пользователя, права которого были получены, возможно с помощью команды su.
Значение переменной $EUID необязательно должно совпадать с содержимым переменной $UID.
$FUNCNAME
имя текущей функции
xyz23 ()
{
echo "Исполняется функция $FUNCNAME." # Исполняется функция xyz23.
}
xyz23
echo "FUNCNAME = $FUNCNAME" # FUNCNAME =
# Пустое (Null) значение за пределеми функций.
$GLOBIGNORE
Перечень шаблонных символов, которые будут проигнорированы при выполнении подстановки имен файлов (globbing) .
$GROUPS
группы, к которым принадлежит текущий пользователь
Это список групп (массив) идентификационных номеров групп для текущего пользователя, как эо записано в /etc/passwd.
root# echo $GROUPS
0
root# echo ${GROUPS[1]}
1
root# echo ${GROUPS[5]}
6
$HOME
домашний каталог пользователя, как правило это /home/username (см. Пример 9-13)
$HOSTNAME
Сетевое имя хоста устанавливается командой hostname во время исполнения инициализирующих сценариев на загрузке системы. Внутренняя переменная $HOSTNAME Bash получает свое значение посредством вызова функции gethostname(). См. так же Пример 9-13.
$HOSTTYPE
тип машины
Подобно $MACHTYPE, идентифицирует аппаратную архитектуру.
bash$ echo $HOSTTYPE
i686
$IFS
разделитель полей во вводимой строке (IFS -- Input Field Separator)
По-умолчанию -- пробельный символ (пробел, табуляция и перевод строки), но может быть изменен, например, для разбора строк, в которых отдельные поля разделены запятыми. Обратите внимание: при составлении содержимого переменной $*, Bash использует первый символ из $IFS для разделения аргументов. См. Пример 5-1.
bash$ echo $IFS | cat -vte
$
bash$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z
При всем при том следует помнить, что при использовании $IFS пробельные символы обрабатываются несколько иначе, чем все остальные.
Пример 9-1. $IFS и пробельные символы
#!/bin/bash
# При использовании $IFS, пробельные символы обрабатываются иначе, чем все остальные.
output_args_one_per_line()
{
for arg
do echo "[$arg]"
done
}
echo; echo "IFS=" ""
echo "-------"
IFS=" "
var=" a b c "
output_args_one_per_line $var # output_args_one_per_line `echo " a b c "`
#
# [a]
# [b]
# [c]
echo; echo "IFS=:"
echo "-----"
IFS=:
var=":a::b:c:::" # То же самое, только пробелы зменены символом ":".
output_args_one_per_line $var
#
# []
# [a]
# []
# [b]
# [c]
# []
# []
# []
# То же самое происходит и с разделителем полей "FS" в awk.
# Спасибо Stephane Chazelas.
echo
exit 0
(Спасибо S. C., за разъяснения и примеры.)
$LC_COLLATE
Чаще всего устанавливается в .bashrc или /etc/profile, эта переменная задает порядок сортировки символов, в операциях подстановки имен файлов и в поиске по шаблону. При неверной настройке переменной LC_COLLATE можно получить весьма неожиданные результаты.
Начиная с версии 2.05, Bash, в операциях подстановки имен файлов, не делает различий между символами верхнего и нижнего регистров, в диапазонах символов в квадратных скобках. Например,, ls [A-M]* выведет как File1.txt, так и file1.txt. Возврат к общепринятому стандарту поведения шаблонов в квадратных скобках выполняется установкой переменной LC_COLLATE в значение C командой export LC_COLLATE=C в файле /etc/profile и/или ~/.bashrc.
$LC_CTYPE
Эта внутренняя переменная определяет кодировку символов. Используется в операциях подстановки и поиске по шаблону.
$LINENO
Номер строки исполняемого сценария. Эта переменная имеет смысл только внутри исполняемого сценария и чаще всего применяется в отладочных целях.