Перейти к основному содержанию
Рецепты Linux

Main navigation

  • Основы
  • Система
  • Команды
  • Программы
  • Дистро
  • Интерфейсы
  • Устройства
  • Доки
User account menu
  • Войти

Строка навигации

  1. Главная
  2. ABS Guide
  3. Часть 4. Материал повышенной сложности

Глава 34. Bash, версия 2

Текущая версия 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:
# Упростите логику сценария.

Notes

[64]

Chet Ramey обещал ввести в Bash ассоциативные массивы (они хорошо знакомы программистам, работающим с языком Perl) в одном из следующих релизов Bash.

Перекрёстные ссылки книги для Глава 34. Bash, версия 2

  • 33.10. Сценарии командной оболочки под Windows
  • Вверх
  • Глава 35. Замечания и дополнения

Book navigation

  • Содержание
  • Часть 1. Введение
  • Часть 2. Основы
  • Часть 3. Углубленный материал
  • Часть 4. Материал повышенной сложности
    • Глава 18. Регулярные выражения
    • Глава 19. Подоболочки, или Subshells
    • Глава 20. Ограниченный режим командной оболочки
    • Глава 21. Подстановка процессов
    • Глава 22. Функции
    • Глава 23. Псевдонимы
    • Глава 24. Списки команд
    • Глава 25. Массивы
    • Глава 26. Файлы
    • Глава 27. /dev и /proc
    • Глава 28. /dev/zero и /dev/null
    • Глава 29. Отладка сценариев
    • Глава 30. Необязательные параметры (ключи)
    • Глава 31. Широко распространенные ошибки
    • Глава 32. Стиль программирования
    • Глава 33. Разное
    • Глава 34. Bash, версия 2
  • Глава 35. Замечания и дополнения
  • Библиография
  • Приложение A. Дополнительные примеры сценариев
  • Приложение B. Справочная информация
  • Приложение C. Маленький учебник по Sed и Awk
  • Приложение D. Коды завершения, имеющие предопределенный смысл
  • Приложение E. Подробное введение в операции ввода-вывода и перенаправление ввода-вывода
  • Приложение F. Системные каталоги
  • Приложение G. Локализация
  • Приложение H. История команд
  • Приложение I. Пример файла .bashrc
  • Приложение J. Преобразование пакетных (*.bat) файлов DOS в сценарии командной оболочки
  • Приложение K. Упражнения
  • Приложение L. Хронология
  • Приложение M. Авторские права

Последние материалы

  • Утилита sensors
    21 hour ago
  • Сканер Rkhunter
    1 week 1 day ago
  • Программа resize2fs
    1 week 6 days ago
  • Аудиопроигрыватель QMMP
    2 weeks 5 days ago
  • Программа Timeshift
    3 weeks 4 days ago
RSS feed

Secondary menu

  • О проекте

© 2008–2025 Олег Меньшенин mensh@yandex.ru