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

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

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Мендель Купер, "Искусство программирования на языке сценариев командной оболочки" бесплатно, без регистрации.
Перейти на страницу:

# Вероятно из-за ошибок округления и несовершенства генератора случайных чисел.

echo


# }


exit 0


# Самое время задуматься над тем, является ли сценарий удобным средством

#+ для выполнения большого количества столь сложных вычислений.

#

# Тем не менее, этот пример может расцениваться как

# 1) Доказательство возможностей языка командной оболочки.

# 2) Прототип для "обкатки" алгоритма перед тем как перенести

#+ его на высокоуровневые языки программирования компилирующего типа.

dc

Утилита dc (desk calculator) -- это калькулятор, использующий "Обратную Польскую Нотацию", и ориентированный на работу со стеком.

Многие стараются избегать испоьзования dc, из-за непривычной формы записи операндов и операций. Однако, dc имеет и своих сторонников.

Пример 12-36. Преобразование чисел из десятичной в шестнадцатиричную систему счисления

#!/bin/bash

# hexconvert.sh: Преобразование чисел из десятичной в шестнадцатиричную систему счисления.


BASE=16 # Шестнадцатиричная.


if [ -z "$1" ]

then

echo "Порядок использования: $0 number"

exit $E_NOARGS

# Необходим аргумент командной строки.

fi

# Упражнение: добавьте проверку корректности аргумента.


hexcvt ()

{

if [ -z "$1" ]

then

echo 0

return # "Return" 0, если функции не был передан аргумент.

fi


echo ""$1" "$BASE" o p" | dc

# "o" устанавливает основание системы счисления для вывода.

# "p" выводит число, находящееся на вершине стека.

# См. 'man dc'.

return

}


hexcvt "$1"


exit 0

Изучение страниц info dc позволит детальнее разобраться с утилитой. Однако, отряд "гуру", которые могут похвастать своим знанием этой мощной, но весьма запутанной утилиты, весьма немногочислен.

Пример 12-37. Разложение числа на простые множители

#!/bin/bash

# factr.sh: Разложение числа на простые множители


MIN=2 # Не работает с числами меньше 2.

E_NOARGS=65

E_TOOSMALL=66


if [ -z $1 ]

then

echo "Порядок использования: $0 number"

exit $E_NOARGS

fi


if [ "$1" -lt "$MIN" ]

then

echo "Исходное число должно быть больше или равно $MIN."

exit $E_TOOSMALL

fi


# Упражнение: Добавьте проверку типа числа (не целые числа должны отвергаться).


echo "Простые множители для числа $1:"

# ---------------------------------------------------------------------------------

echo "$1[p]s2[lip/dli%0=1dvsr]s12sid2%0=13sidvsr[dli%0=1lrli2+dsi!>.]ds.xd1<2" | dc

# ---------------------------------------------------------------------------------

# Автор вышеприведенной строки: Michel Charpentier < [email protected]>.

# Используется с его разрешения (спасибо).


exit 0

awk

Еще один способ выполнения математических операций, над числами с плавающей запятой, состоит в создании сценария-обертки, использующего математические функции awk.

Пример 12-38. Расчет гипотенузы прямоугольного треугольника

#!/bin/bash

# hypotenuse.sh: Возвращает "гипотенузу" прямоугольного треугольника.

# ( корень квадратный от суммы квадратов катетов)


ARGS=2 # В сценарий необходимо передать два катета.

E_BADARGS=65 # Ошибка в аргументах.


if [ $# -ne "$ARGS" ] # Проверка количества аргументов.

then

echo "Порядок использования: `basename $0` катет_1 катет_2"

exit $E_BADARGS

fi


AWKSCRIPT=' { printf( "%3.7fn", sqrt($1*$1 + $2*$2) ) } '

# команды и параметры, передаваемые в awk


echo -n "Гипотенуза прямоугольного треугольника, с катетами $1 и $2, = "

echo $1 $2 | awk "$AWKSCRIPT"


exit 0


12.9. Прочие команды

Команды, которые нельзя отнести ни к одной из вышеперечисленных категорий

jot, seq

Эти утилиты выводят последовательность целых чисел с шагом, заданным пользователем.

По-умолчанию, выводимые числа отделяются друг от друга символом перевода строки, однако, с помощью ключа -s может быть задан другой разделитель.

bash$ seq 5

1

2

3

4

5


bash$ seq -s : 5

1:2:3:4:5


Обе утилиты, и jot, и seq, очень удобно использовать для генерации списка аргументов в цикле for.

Пример 12-39. Использование seq для генерации списка аргументов цикла for

#!/bin/bash

# Утилита "seq"


echo


for a in `seq 80` # или так: for a in $( seq 80 )

# То же самое, что и for a in 1 2 3 4 5 ... 80 (но как экономит время и силы!).

# Можно использовать и 'jot' (если эта утилита имеется в системе).

do

echo -n "$a "

done # 1 2 3 4 5 ... 80

# Пример использования вывода команды для генерации

# [списка] аргументов цикла "for".


echo; echo


COUNT=80 # Да, 'seq' допускает указание переменных в качестве параметра.


for a in `seq $COUNT` # или так: for a in $( seq $COUNT )

do

echo -n "$a "

done # 1 2 3 4 5 ... 80


echo; echo


BEGIN=75

END=80


for a in `seq $BEGIN $END`

# Если "seq" передаются два аргумента, то первый означает начальное число последовательности,

#+ второй -- последнее,

do

echo -n "$a "

done # 75 76 77 78 79 80


echo; echo


BEGIN=45

INTERVAL=5

END=80


for a in `seq $BEGIN $INTERVAL $END`

# Если "seq" передется три аргумента, то первый аргумент -- начальное число в последовательности,

#+ второй -- шаг последовательности,

#+ и третий -- последнее число в последовательности.

do

echo -n "$a "

done # 45 50 55 60 65 70 75 80


echo; echo


exit 0

getopt

Команда getopt служит для разбора командной строки, выделяя из нее ключи -- символы, с предшествующим знаком дефис. Этой утилите имеется, встроенный в Bash, аналог -- getopts, более мощная и универсальная команда.

Пример 12-40. Использование getopt для разбора аргументов командной строки

#!/bin/bash

# ex33a.sh


# Попробуйте следующие варианты вызова этого сценария.

# sh ex33a -a

# sh ex33a -abc

# sh ex33a -a -b -c

# sh ex33a -d

# sh ex33a -dXYZ

# sh ex33a -d XYZ

# sh ex33a -abcd

# sh ex33a -abcdZ

# sh ex33a -z

# sh ex33a a

# Объясните полученные результаты.


E_OPTERR=65


if [ "$#" -eq 0 ]

then # Необходим по меньшей мере один аргумент.

echo "Порядок использования: $0 -[options a,b,c]"

exit $E_OPTERR

fi


set -- `getopt "abcd:" " [email protected]"`

# Запись аргументов командной строки в позиционные параметры.

# Что произойдет, если вместо " [email protected]" указать "$*"?


while [ ! -z "$1" ]

do

case "$1" in

-a) echo "Опция "a"";;

-b) echo "Опция "b"";;

-c) echo "Опция "c"";;

-d) echo "Опция "d" $2";;

*) break;;

esac


shift

done


# Вместо 'getopt' лучше использовать встроенную команду 'getopts',

# См. "ex33.sh".


exit 0

run-parts

Команда run-parts[ 33 ] запускает на исполнение все сценарии, в порядке возрастания имен файлов-сценариев, в заданном каталоге. Естественно, файлы сценариев должны иметь права на исполнение.

Демон crond вызывает run-parts для запуска сценариев из каталогов /etc/cron.*.

yes

По-умолчанию, команда yes выводит на stdout непрерывную последовательность символов y, разделенных символами перевода строки. Исполнение команды можно прервать комбинацией клавиш control-c. Команду yes можно заставить выводить иную последовательность символов. Теперь самое время задаться вопросом о практической пользе этой команды. Основное применение этой команды состоит в том, что вывод от нее может быть передан, через конвейер, другой команде, ожидающей реакции пользователя. В результате получается, своего рода, слабенькая версия команды expect.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*