Опубликовано Bash в Ср, 23/12/2009 — 21:04
Текущая версия Bash, та, которая скорее всего установлена в вашей системе, фактически — 2.XX.Y.
-
bash$ echo $BASH_VERSION
-
2.05.b.0(1)-release
-
В этой версии классического языка сценариев Bash были добавлены
переменные-массивы, [64] расширение строк и подстановка
параметров, улучшен метод косвенных ссылок на
переменные.
Пример 34-1. Расширение строк
-
#!/bin/bash
-
# «Расширение» строк (String expansion).
-
# Введено в Bash, начиная с версии 2.
-
# Строки вида $’xxx’
-
# могут содержать дополнительные экранированные символы.
-
echo $‘Звонок звенит 3 раза \a \a \a’
-
echo $‘Три перевода формата \f \f \f’
-
echo $’10 новых строк \n\n\n\n\n\n\n\n\n\n’
-
exit 0
Пример 34-2. Косвенные ссылки на переменные — новый метод
-
#!/bin/bash
-
# Косвенные ссылки на переменные.
-
a=letter_of_alphabet
-
letter_of_alphabet=z
-
echo «a = $a« # Прямая ссылка.
-
echo «Now a = ${!a}« # Косвенная ссылка.
-
# Форма записи ${!variable} намного удобнее старой «eval var1=\$$var2»
-
echo
-
t=table_cell_3
-
table_cell_3=24
-
echo «t = ${!t}« # t = 24
-
table_cell_3=387
-
echo «Значение переменной t изменилось на ${!t}« # 387
-
# Теперь их можно использовать для ссылок на элементы массива,
-
# или для эмуляции многомерных массивов.
-
# Было бы здорово, если бы косвенные ссылки допускали индексацию.
-
exit 0
Пример 34-3. Простая база данных, с применением косвенных ссылок
-
#!/bin/bash
-
# resistor-inventory.sh
-
# Простая база данных, с применением косвенных ссылок.
-
# ============================================================== #
-
# Данные
-
B1723_value=470 # сопротивление (Ом)
-
B1723_powerdissip=.25 # рассеиваемая мощность (Вт)
-
B1723_colorcode=«желтый-фиолетовый-коричневый» # цветовая маркировка
-
B1723_loc=173 # где
-
B1723_inventory=78 # количество (шт)
-
B1724_value=1000
-
B1724_powerdissip=.25
-
B1724_colorcode=«коричневый-черный-красный»
-
B1724_loc=24N
-
B1724_inventory=243
-
B1725_value=10000
-
B1725_powerdissip=.25
-
B1725_colorcode=«коричневый-черный-оранжевый»
-
B1725_loc=24N
-
B1725_inventory=89
-
# ============================================================== #
-
echo
-
PS3=‘Введите ноиер: ‘
-
echo
-
select catalog_number in «B1723» «B1724» «B1725»
-
do
-
Inv=${catalog_number}_inventory
-
Val=${catalog_number}_value
-
Pdissip=${catalog_number}_powerdissip
-
Loc=${catalog_number}_loc
-
Ccode=${catalog_number}_colorcode
-
echo
-
echo «Номер по каталогу $catalog_number:»
-
echo «Имеется в наличии ${!Inv} шт. [${!Val} Ом / ${!Pdissip} Вт].»
-
echo «Находятся в лотке # ${!Loc}.»
-
echo «Цветовая маркировка: \»${!Ccode}\».»
-
break
-
done
-
echo; echo
-
# Упражнение:
-
# ———-
-
# Переделайте этот сценарий так, чтобы он использовал массивы вместо косвенных ссылок.
-
# Какой из вариантов более простой и интуитивный?
-
# Примечание:
-
# ———-
-
# Язык командной оболочки не очень удобен для написания приложений,
-
#+ работающих с базами данных.
-
# Для этой цели лучше использовать языки программирования, имеющие
-
#+ развитые средства для работы со структурами данных,
-
#+ такие как C++ или Java (может быть Perl).
-
exit 0
Пример 34-4. Массивы и другие хитрости для раздачи колоды карт в четыре руки
-
#!/bin/bash
-
# На старых системах может потребоваться вставить #!/bin/bash2.
-
# Карты:
-
# раздача в четыре руки.
-
UNPICKED=0
-
PICKED=1
-
DUPE_CARD=99
-
LOWER_LIMIT=0
-
UPPER_LIMIT=51
-
CARDS_IN_SUIT=13
-
CARDS=52
-
declare -a Deck
-
declare -a Suits
-
declare -a Cards
-
# Проще и понятнее было бы, имей мы дело
-
# с одним 3-мерным массивом.
-
# Будем надеяться, что в будущем, поддержка многомерных массивов будет введена в Bash.
-
initialize_Deck ()
-
{
-
i=$LOWER_LIMIT
-
until [ «$i« -gt $UPPER_LIMIT ]
-
do
-
Deck[i]=$UNPICKED # Пометить все карты в колоде «Deck», как «невыданная».
-
let «i += 1»
-
done
-
echo
-
}
-
initialize_Suits ()
-
{
-
Suits[0]=Т # Трефы
-
Suits[1]=Б # Бубны
-
Suits[2]=Ч # Червы
-
Suits[3]=П # Пики
-
}
-
initialize_Cards ()
-
{
-
Cards=(2 3 4 5 6 7 8 9 10 В Д K Т)
-
# Альтернативный способ инициализации массива.
-
}
-
pick_a_card ()
-
{
-
card_number=$RANDOM
-
let «card_number %= $CARDS«
-
if [ «${Deck[card_number]}« -eq $UNPICKED ]
-
then
-
Deck[card_number]=$PICKED
-
return $card_number
-
else
-
return $DUPE_CARD
-
fi
-
}
-
parse_card ()
-
{
-
number=$1
-
let «suit_number = number / CARDS_IN_SUIT»
-
suit=${Suits[suit_number]}
-
echo -n «$suit-«
-
let «card_no = number % CARDS_IN_SUIT»
-
Card=${Cards[card_no]}
-
printf %-4s $Card
-
# Вывод по столбцам.
-
}
-
seed_random () # Переустановка генератора случайных чисел.
-
{
-
seed=`eval date +%s`
-
let «seed %= 32766»
-
RANDOM=$seed
-
}
-
deal_cards ()
-
{
-
echo
-
cards_picked=0
-
while [ «$cards_picked« -le $UPPER_LIMIT ]
-
do
-
pick_a_card
-
t=$?
-
if [ «$t« -ne $DUPE_CARD ]
-
then
-
parse_card $t
-
u=$cards_picked+1
-
# Возврат к индексации с 1 (временно).
-
let «u %= $CARDS_IN_SUIT«
-
if [ «$u« -eq 0 ] # вложенный if/then.
-
then
-
echo
-
echo
-
fi
-
# Смена руки.
-
let «cards_picked += 1»
-
fi
-
done
-
echo
-
return 0
-
}
-
# Структурное программирование:
-
# вся логика приложения построена на вызове функций.
-
#================
-
seed_random
-
initialize_Deck
-
initialize_Suits
-
initialize_Cards
-
deal_cards
-
exit 0
-
#================
-
# Упражнение 1:
-
# Добавьте комментарии, чтобы до конца задокументировать этот сценарий.
-
# Упражнение 2:
-
# Исправьте сценарий так, чтобы карты в каждой руке выводились отсортированными по масти.
-
# Вы можете добавить и другие улучшения.
-
# Упражнение 3:
-
# Упростите логику сценария.
[64] Chet Ramey обещал ввести в Bash ассоциативные массивы (они хорошо знакомы программистам, работающим с языком Perl) в одном из следующих релизов Bash.
- Страница для печати
- 8004 просмотра