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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 45 46 47 48 49 50 51 52 53 ... 96

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

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.

1 ... 45 46 47 48 49 50 51 52 53 ... 96
На этом сайте Вы можете читать книги онлайн бесплатно русская версия Искусство программирования на языке сценариев командной оболочки - Мендель Купер.
Книги, аналогичгные Искусство программирования на языке сценариев командной оболочки - Мендель Купер

Оставить комментарий