Мендель Купер - Искусство программирования на языке сценариев командной оболочки

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.
Жалоба
Напишите нам, и мы в срочном порядке примем меры.
Описание книги "Искусство программирования на языке сценариев командной оболочки"
Описание и краткое содержание "Искусство программирования на языке сценариев командной оболочки" читать бесплатно онлайн.
Данное руководство не предполагает наличие у читателя познаний в области программирования на языке сценариев, однако, быстро восполняет этот недостаток, постепенно, шаг за шагом раскрывая мудрость и красоту UNIX. Это руководство может рассматриваться как учебник, предназначенный для самостоятельного изучения или как справочник по программированию на shell. Руководство снабжено серией хорошо прокомментированных примеров, поскольку лучший путь к изучению языка сценариев -- это написание сценариев.
exchange()
{
# Поменять местами два элемента массива.
local temp=${Countries[$1]} # Временная переменная
Countries[$1]=${Countries[$2]}
Countries[$2]=$temp
return
}
declare -a Countries # Объявление массива,
#+ необязательно, поскольку он явно инициализируется ниже.
# Допустимо ли выполнять инициализацию массива в нескольки строках?
# ДА!
Countries=(Нидерланды Украина Заир Турция Россия Йемен Сирия \
Бразилия Аргентина Никарагуа Япония Мексика Венесуэла Греция Англия \
Израиль Перу Канада Оман Дания Уэльс Франция Кения \
Занаду Катар Лихтенштейн Венгрия)
# "Занаду" -- это мифическое государство, где, согласно Coleridge,
#+ Kubla Khan построил величественный дворец.
clear # Очистка экрана.
echo "0: ${Countries[*]}" # Список элементов несортированного массива.
number_of_elements=${#Countries[@]}
let "comparisons = $number_of_elements - 1"
count=1 # Номер прохода.
while [ "$comparisons" -gt 0 ] # Начало внешнего цикла
do
index=0 # Сбросить индекс перед началом каждого прохода.
while [ "$index" -lt "$comparisons" ] # Начало внутреннего цикла
do
if [ ${Countries[$index]} \> ${Countries[`expr $index + 1`]} ]
# Если элементы стоят не по порядку...
# Оператор \> выполняет сравнение ASCII-строк
#+ внутри одиночных квадратных скобок.
# if [[ ${Countries[$index]} > ${Countries[`expr $index + 1`]} ]]
#+ дает тот же результат.
then
exchange $index `expr $index + 1` # Поменять местами.
fi
let "index += 1"
done # Конец внутреннего цикла
let "comparisons -= 1" # Поскольку самый "тяжелый" элемент уже "опустился" на дно,
#+ то на каждом последующем проходе нужно выполнять на одно сравнение меньше.
echo
echo "$count: ${Countries[@]}" # Вывести содержимое массива после каждого прохода.
echo
let "count += 1" # Увеличить счетчик проходов.
done # Конец внешнего цикла
exit 0
--
Можно ли вложить один массив в другой?
#!/bin/bash
# Вложенный массив.
# Автор: Michael Zick.
AnArray=( $(ls --inode --ignore-backups --almost-all \
--directory --full-time --color=none --time=status \
--sort=time -l ${PWD} ) ) # Команды и опции.
# Пробелы важны . . .
SubArray=( ${AnArray[@]:11:1} ${AnArray[@]:6:5} )
# Массив имеет два элемента, каждый из которых, в свою очередь, является массивом.
echo "Текущий каталог и дата последнего изменения:"
echo "${SubArray[@]}"
exit 0
--
Вложенные массивы, в комбинации с косвенными ссылками, предоставляют в распоряжение программиста ряд замечательных возможностей
Пример 25-7. Вложенные массивы и косвенные ссылки
#!/bin/bash
# embedded-arrays.sh
# Вложенные массивы и косвенные ссылки.
# Автор: Dennis Leeuw.
# Используется с его разрешения.
# Дополнен автором документа.
ARRAY1=(
VAR1_1=value11
VAR1_2=value12
VAR1_3=value13
)
ARRAY2=(
VARIABLE="test"
STRING="VAR1=value1 VAR2=value2 VAR3=value3"
ARRAY21=${ARRAY1[*]}
) # Вложение массива ARRAY1 в массив ARRAY2.
function print () {
OLD_IFS="$IFS"
IFS=$'\n' # Вывод каждого элемента массива
#+ в отдельной строке.
TEST1="ARRAY2[*]"
local ${!TEST1} # Посмотрите, что произойдет, если убрать эту строку.
# Косвенная ссылка.
# Позволяет получить доступ к компонентам $TEST1
#+ в этой функции.
# Посмотрим, что получилось.
echo
echo "\$TEST1 = $TEST1" # Просто имя переменной.
echo; echo
echo "{\$TEST1} = ${!TEST1}" # Вывод на экран содержимого переменной.
# Это то, что дает
#+ косвенная ссылка.
echo
echo "-------------------------------------------"; echo
echo
# Вывод переменной
echo "Переменная VARIABLE: $VARIABLE"
# Вывод элементов строки
IFS="$OLD_IFS"
TEST2="STRING[*]"
local ${!TEST2} # Косвенная ссылка (то же, что и выше).
echo "Элемент VAR2: $VAR2 из строки STRING"
# Вывод элемента массива
TEST2="ARRAY21[*]"
local ${!TEST2} # Косвенная ссылка.
echo "Элемент VAR1_1: $VAR1_1 из массива ARRAY21"
}
echo
exit 0
--
С помощью массивов, на языке командной оболочки, вполне возможно реализовать алгоритм Решета Эратосфена. Конечно же -- это очень ресурсоемкая задача. В виде сценария она будет работать мучительно долго, так что лучше всего реализовать ее на каком либо другом, компилирующем, языке программирования, таком как C.
Пример 25-8. Пример реализации алгоритма Решето Эратосфена
#!/bin/bash
# sieve.sh
# Решето Эратосфена
# Очень старый алгоритм поиска простых чисел.
# Этот сценарий выполняется во много раз медленнее
# чем аналогичная программа на C.
LOWER_LIMIT=1 # Начиная с 1.
UPPER_LIMIT=1000 # До 1000.
# (Вы можете установить верхний предел и выше... если вам есть чем себя занять.)
PRIME=1
NON_PRIME=0
declare -a Primes
# Primes[] -- массив.
initialize ()
{
# Инициализация массива.
i=$LOWER_LIMIT
until [ "$i" -gt "$UPPER_LIMIT" ]
do
Primes[i]=$PRIME
let "i += 1"
done
# Все числа в заданном диапазоне считать простыми,
# пока не доказано обратное.
}
print_primes ()
{
# Вывод индексов элементов массива Primes[], которые признаны простыми.
i=$LOWER_LIMIT
until [ "$i" -gt "$UPPER_LIMIT" ]
do
if [ "${Primes[i]}" -eq "$PRIME" ]
then
printf "%8d" $i
# 8 пробелов перед числом придают удобочитаемый табличный вывод на экран.
fi
let "i += 1"
done
}
sift () # Отсеивание составных чисел.
{
let i=$LOWER_LIMIT+1
# Нам известно, что 1 -- это простое число, поэтому начнем с 2.
until [ "$i" -gt "$UPPER_LIMIT" ]
do
if [ "${Primes[i]}" -eq "$PRIME" ]
# Не следует проверять вторично числа, которые уже признаны составными.
then
t=$i
while [ "$t" -le "$UPPER_LIMIT" ]
do
let "t += $i "
Primes[t]=$NON_PRIME
# Все числа, которые делятся на $t без остатка, пометить как составные.
done
fi
let "i += 1"
done
}
# Вызов функций.
initialize
sift
print_primes
# Это называется структурным программированием.
echo
exit 0
# ----------------------------------------------- #
# Код, приведенный ниже, не исполняется из-за команды exit, стоящей выше.
# Улучшенная версия, предложенная Stephane Chazelas,
# работает несколько быстрее.
# Должен вызываться с аргументом командной строки, определяющем верхний предел.
UPPER_LIMIT=$1 # Из командной строки.
let SPLIT=UPPER_LIMIT/2 # Рассматривать делители только до середины диапазона.
Primes=( '' $(seq $UPPER_LIMIT) )
i=1
until (( ( i += 1 ) > SPLIT )) # Числа из верхней половины диапазона могут не рассматриваться.
do
if [[ -n $Primes[i] ]]
then
t=$i
until (( ( t += i ) > UPPER_LIMIT ))
do
Primes[t]=
done
fi
done
echo ${Primes[*]}
exit 0
Сравните этот сценарий с генератором простых чисел, не использующим массивов, Пример A-18.
--
Массивы позволяют эмулировать некоторые структуры данных, поддержка которых в Bash не предусмотрена.
Пример 25-9. Эмуляция структуры "СТЕК" ("первый вошел -- последний вышел")
#!/bin/bash
# stack.sh: Эмуляция структуры "СТЕК" ("первый вошел -- последний вышел")
# Подобно стеку процессора, этот "стек" сохраняет и возвращает данные по принципу
#+ "первый вошел -- последний вышел".
BP=100 # Базовый указатель на массив-стек.
# Дно стека -- 100-й элемент.
SP=$BP # Указатель вершины стека.
# Изначально -- стек пуст.
Data= # Содержимое вершины стека.
# Следует использовать дополнительную переменную,
#+ из-за ограничений на диапазон возвращаемых функциями значений.
declare -a stack
push() # Поместить элемент на вершину стека.
{
if [ -z "$1" ] # А вообще, есть что помещать на стек?
then
return
fi
let "SP -= 1" # Переместить указатель стека.
stack[$SP]=$1
return
}
pop() # Снять элемент с вершины стека.
{
Data= # Очистить переменную.
if [ "$SP" -eq "$BP" ] # Стек пуст?
then
return
fi # Это предохраняет от выхода SP за границу стека -- 100,
Data=${stack[$SP]}
let "SP += 1" # Переместить указатель стека.
return
}
status_report() # Вывод вспомогательной информации.
{
echo "-------------------------------------"
echo "ОТЧЕТ"
echo "Указатель стека SP = $SP"
echo "Со стека был снят элемент \""$Data"\""
echo "-------------------------------------"
echo
}
# =======================================================
# А теперь позабавимся.
echo
# Попробуем вытолкнуть что-нибудь из пустого стека.
pop
status_report
echo
push garbage
pop
status_report # Втолкнуть garbage, вытолкнуть garbage.
value1=23; push $value1
value2=skidoo; push $value2
value3=FINAL; push $value3
pop # FINAL
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!
Похожие книги на "Искусство программирования на языке сценариев командной оболочки"
Книги похожие на "Искусство программирования на языке сценариев командной оболочки" читать онлайн или скачать бесплатно полные версии.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
Отзывы о "Мендель Купер - Искусство программирования на языке сценариев командной оболочки"
Отзывы читателей о книге "Искусство программирования на языке сценариев командной оболочки", комментарии и мнения людей о произведении.