Библиотека сайта rus-linux.net
Руководство по Bash для начинающих | ||
---|---|---|
Назад | Глава 10: Подробнее о переменных | Вперед |
Переменные массивы
Создание массивов
Массив - это переменная, в которой хранится несколько значений. Любая переменная может использоваться как массив. На максимальный размер массива ограничений нет и нет никаких других требований к элементам массива, за исключением лишь того, что элементы массива имеют индексы и значения индексов идут подряд. Массивы начинаются с нулевого элемента: индекс первого элемента равен 0.
Косвенное объявление, задающее переменную, выполняется следующим образом:
ARRAY[INDEXNR]=value
INDEXNR рассматривается как арифметическое выражение, результат вычисления которого должен быть положительным числом.
Явное объявление массива выполняется с помощью встроенной команды declare:
declare -a ARRAYNAME
Также допускается объявление с указанием индекса, но индекс будет игнорироваться. С помощью встроенных команд declare и readonly для массива можно определять атрибуты. Атрибуты действуют для всех переменных в массиве, у вас не может быть смешанных массивов.
Массив переменных можно также объявить с помощью инструкции присваивания следующего формата:
ARRAY=(value1 value2 ... valueN)
Каждое значение value
в этом формате имеет вид [номериндекса =]строка. Индекс не является обязательным. Если он указан, то он используется в инструкции присваивания; в противном случае в качестве индекса используется значение индекса, которое уже было назначено, плюс один. Этот формат можно также использовать в команде declare. Если индексы не указываются, индексация начинается с нуля.
Добавление отсутствующих или дополнительных элементов массива осуществляется следующим образом:
ARRAYNAME[indexnumber]=value
Помните, что во встроенной команде read есть параметр -a
, который позволяет читать и назначать значения элементам массива.
Получение доступа к содержимому массива
Чтобы получить доступ к содержимому элемента в массиве, используйте фигурные скобки. Как показано в следующем примере, они необходимы для того, чтобы отключить интерпретацию, выполняемую командной оболочкой, с помощью которой происходит подстановка операторов. Если в качестве номера индекса указывается "@" или "*", то выдаются все элементы массива.
[bob in ~] ARRAY=(one two three) [bob in ~] echo ${ARRAY[*]} one two three [bob in ~] echo $ARRAY[*] one[*] [bob in ~] echo ${ARRAY[2]} three [bob in ~] ARRAY[3]=four [bob in ~] echo ${ARRAY[*]} one two three four
Если переменная массива указывается без указания номера индекса, то в результате будет получено содержимое первого элемента массива, т. е. элемента с нулевым индексом.
Удаление переменных массивов
Для уничтожения массивов или элементов массива используется встроенная команда unset:
[bob in ~] unset ARRAY[1] [bob in ~] echo ${ARRAY[*]} one three four [bob in ~] unset ARRAY [bob in ~] echo ${ARRAY[*]} <--no output-->
Примеры массивов
Практические примеры использования массивов найти трудно. Вы легко найдете множество скриптов, которые в вашей системе, в действительности, ничего не делают, но в них используются массивы для вычисления математических рядов. И это будут одни из наиболее интересных примеров ... В большинстве скриптов всего лишь в упрощенном виде показывается, что вы, теоретически, можете делать с массивами.
Причина этого состоит в том, что массивы являются сравнительно сложными структурами. Вы обнаружите, что большинство практических примеров, в которых используются массивы, уже реализованы в вашей системе, но на более низком уровне — на языке программирования C, на котором написаны большинство команд UNIX. Хорошим примером является встроенная команда Bash history. Те читатели, которым это интересно, могут поискать исходный код Bash в директории built-ins
и взглянуть на файл fc.def
, используемый при компиляции встроенных команд.
Еще одна причина того, что трудно найти хорошие примеры, состоит в том, что массивы поддерживаются не во всех командных оболочках, и из-за них нарушается совместимость.
После многодневного поиска, я, наконец, нашел приведенный ниже пример, работающий у Интернет-провайдера. С помощью этого скрипта распространяются конфигурационные файлы веб сервера Apache по хостам на ферме веб-серверов:
#!/bin/bash if [ $(whoami) != 'root' ]; then echo "Must be root to run $0" exit 1; fi if [ -z $1 ]; then echo "Usage: $0 <path/to/httpd.conf>" exit 1 fi httpd_conf_new=$1 httpd_conf_path="/usr/local/apache/conf" login=htuser farm_hosts=(web03 web04 web05 web06 web07) for i in ${farm_hosts[@]}; do su $login -c "scp $httpd_conf_new ${i}:${httpd_conf_path}" su $login -c "ssh $i sudo /usr/local/apache/bin/apachectl graceful" done exit 0
Первые две проверки выполняются для того, чтобы узнать, сможет ли пользователь, имеющий надлежащие права доступа, запускать скрипт с правильными аргументами. Имена хостов, которые необходимо сконфигурировать, перечислены в массиве farm_hosts
. Затем на все эти хосты передается конфигурационный файл Apache, после чего перезапускается демон. Обратите внимание на использование команд из пакета Secure Shell suite, обеспечивающих шифрование соединения с удаленными узлами.
Спасибо Евгению и его коллегам за этот вклад.
Следующий пример представил Дэн Рихтер (Dan Richter). Он столкнулся со следующей проблемой:
"... На сайте моей компании есть демонстрационные примеры, и каждую неделю кто-нибудь должен все их проверять. Поэтому у меня есть задание cron, которое заполняет массив возможными кандидатами; в задании cron для определения недели в году используется команда date +%W
и для того, чтобы получить правильный индекс, выполняется операция по модулю. Счастливчик получает уведомление по электронной почте".
И ниже приводится способ ее решения:
#!/bin/bash # This is get-tester-address.sh # # First, we test whether bash supports arrays. # (Support for arrays was only added recently.) # whotest[0]='test' || (echo 'Failure: arrays not supported in this version of bash.' && exit 2) # # Our list of candidates. (Feel free to add or # remove candidates.) # wholist=( 'Bob Smith <bob@example.com>' 'Jane L. Williams <jane@example.com>' 'Eric S. Raymond <esr@example.com>' 'Larry Wall <wall@example.com>' 'Linus Torvalds <linus@example.com>' ) # # Count the number of possible testers. # (Loop until we find an empty string.) # count=0 while [ "x${wholist[count]}" != "x" ] do count=$(( $count + 1 )) done # # Now we calculate whose turn it is. # week=`date '+%W'` # The week of the year (0..53). week=${week#0} # Remove possible leading zero. let "index = $week % $count" # week modulo count = the lucky person email=${wholist[index]} # Get the lucky person's e-mail address. echo $email # Output the person's e-mail address.
Затем этот скрипт будет использован в других скриптах, таких как следующий, в котором используется встраиваемый документ (here document):
email=`get-tester-address.sh` # Find who to e-mail. hostname=`hostname` # This machine's name. # # Send e-mail to the right person. # mail $email -s '[Demo Testing]' <EOF The lucky tester this week is: $email Reminder: the list of demos is here: http://web.example.com:8080/DemoSites (This e-mail was generated by $0 on ${hostname}.) EOF
Предыдущий раздел: | Оглавление | Следующий раздел: |
Типы переменных | Операции над переменными |