Искусство программирования на языке сценариев командной оболочки
Шрифт:
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:
# Упростите логику сценария.
Глава 35. Замечания и дополнения
35.1. От автора
Как я пришел к мысли о написании этой книги? Это необычная история. Случилось это лет несколько тому назад. Мне потребовалось изучить язык командной оболочки -- а что может быть лучше, как не чтение хорошей книги!? Я надеялся купить учебник и справочник, которые охватывали бы в полной мере данную тематику. Я искал книгу, которая возьмет трудные понятия, вывернет их наизнанку и подробно разжует на хорошо откомментированных примерах. В общем, я искал очень хорошую книгу. К сожалению, в природе таковой не существовало, поэтому я счел необходимым написать ее.