I.2. Создание сценариев

Напишите сценарии для выполнения повседневных задач.

Простые задания

Содержимое домашнего каталога

Выполните рекурсивный обход домашнего каталога и сохраните информацию в файл. Сожмите файл. Попросите пользователя вставить дискету и нажать клавишу ENTER. Запишите сжатый файл на дискету.

Замена цикла for циклами while и until

Замените циклы for в Пример 10-1 на while. Подсказка: запишите данные в массив и пройдите в цикле по элементам массива.

Выполнив эту "тяжелую работу", замените циклы, в этом примере, на циклы until .

Изменение межстрочного интервала в текстовом файле

Напишите сценарий, который будет читать текст из заданного файла, и выводить, построчно, на stdout, добавляя при этом дополнительные пустые строки так, чтобы в результате получился вывод с двойным межстрочным интервалом.

Добавьте код, который будет выполнять проверку наличия файла, передаваемого как аргумент.

Когда сценарий будет отлажен, измените его так, чтобы он выводил текстовый файл с тройным межстрочным интервалом.

И наконец, напишите сценарий, который будет удалять пустые строки из заданного файла.

Вывод "задом-на-перед"

Напишите сценарий, который будет выводить себя на stdout, но в обратном порядке.

Автоматическое разархивирование

Для каждого файла, из заданного списка, сценарий должен определить тип архиватора, которым был создан тот или иной файл (с помощью утилиты file). Затем сценарий должен выполнить соответствующую команду разархивации (gunzip, bunzip2, unzip, uncompress или что-то иное). Если файл не является архивом, то сценарий должен оповестить пользователя об этом и ничего не делать с этим файлом.

Уникальный идентификатор системы

Сценарий должен сгенерировать "уникальный" 6-ти разрядный шестнадцатиричный идентификатор системы. Не пользуйтесь дефектной утилитой hostid. Подсказка: md5sum /etc/passwd, затем отберите первые 6 цифр.

Резервное копирование

Сценарий должен создать архив (*.tar.gz) всех файлов в домашнем каталоге пользователя (/home/user-name), которые изменялись в течение последних 24 часов. Подсказка: воспользуйтесь утилитой find.

Простые числа

Сценарий должен вывести (на stdout) все простые числа, в диапазоне от 60000 до 63000. Вывод должен быть отформатирован по столбцам (подсказка: воспользуйтесь командой printf).

Лототрон

Сценарий должен имитировать работу лототрона -- извлекать 5 случайных неповторяющихся чисел в диапазоне 1 - 50. Сценарий должен предусматривать как вывод на stdout, так и запись чисел в файл, кроме того, вместе с числами должны выводиться дата и время генерации данного набора.

Задания повышенной сложности

Управление дисковым пространством

Сценарий должен отыскать в домашнем каталоге пользователя /home/username файлы, имеющие размер больше 100K. Каждый раз предоставляя пользователю возможность удалить или сжать этот файл, затем переходить к поиску следующего файла.

Безопасное удаление

Напишите сценарий "безопасного" удаления файлов -- srm.sh. Файлы, с именами, передаваемыми этому сценарию, не должны удаляться, вместо этого, файлы следует сжать утилитой gzip, если они еще не сжаты (не забывайте про утилиту file), и переместить в каталог /home/username/trash. При старте, сценарий должен удалять из каталога "trash" файлы, которые были созданы более 48 часов тому назад.

Размен монет

Как более рационально собрать сумму в $1.68, используя только монеты, с номиналом не выше 25c? Это будет шесть 25-ти центовых монет, одна десятицентовая, одна пятицентовая и три монеты достоинством в 1 цент.

Учитывая возможность произвольного ввода суммы в долларах и центах ($*.??), найдите такую комбинацию, которая требовала бы наименьшее число монет. Если вы проживаете не в США, то можете использовать свою денежную единицу и номиналы монет. Подсказка: взгляните на Пример 22-4.

Корни квадратного уравнения

Напишите сценарий, который находил бы корни "квадратного " уравнения, вида: Ax^2 + Bx + C = 0. Сценарий должен получать коэффициенты уравнения A, B и C, как аргументы командной строки, и находить корни, с точностью до четвертого знака после запятой.

Подсказка: воспользуйтесь bc, для нахождения решения по хорошо известной формуле: x = ( -B +/- sqrt( B^2 - 4AC ) ) / 2A.

Сумма чисел

Найдите сумму всех пятизначных чисел (в диапазоне 10000 - 99999), которые содержат точно две цифры из следующего набора: { 4, 5, 6 }.

Примеры чисел, удовлетворяющих данному условию: 42057, 74638 и 89515.

Счастливый билет

"Счастливым" считается такой билет, в котором последовательное сложение цифр номера дает число 7. Например, 62431 -- номер "счастливого" билета (6 + 2 + 4 + 3 + 1 = 16, 1 + 6 = 7). Найдите все "счастливые" номера, располагающиеся в диапазоне 1000 - 10000.

Синтаксический анализ

Проанализируйте файл /etc/passwd и выведите его содержимое в табличном виде.

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

Некоторые базы данных и электронные таблицы используют формат CSV (comma-separated values), для хранения данных в файлах. Зачастую, эти файлы должны анализироваться другими приложениями.

Пусть файл содержит следующие данные:

Jones,Bill,235 S. Williams St.,Denver,CO,80221,(303) 244-7989
Smith,Tom,404 Polk Ave.,Los Angeles,CA,90003,(213) 879-5612
...

            Прочитайте данные и выведите их на stdout в виде колонок с
            заголовками.

Выравнивание

Текст вводится с устройства stdin или из файла. Его необходимо вывести на stdout, с выравниванием по ширине, используя задаваемую пользователем ширину строк.

Список рассылки

Напишите сценарий, который использовал бы команду mail, для управления простым списком рассылки. Сценарий должен брать текст ежемесячного информационного бюллетеня из заданного файла, список адресатов из другого файла и выполнять рассылку новостей по электронной почте.

Пароли

Сгенерируйте псевдослучайные 8-ми символьные пароли, используя символы из диапазона [0-9], [A-Z], [a-z]. Каждый пароль должен содержать не менее 2-х цифр.

Сложные задания

Регистрация обращений к файлам

Попробуйте отследить все попытки обращения к файлам в каталоге /etc, в течение дня. Сведения, которые включают в себя время обращения, имя файла, имя пользователя (если имели место какие либо изменения в файлах, то они тоже должны быть отмечены), запишите в виде аккуратно отформатированных записей в логфайл.

Удаление комментариев

Удалите все комментарии из сценария, имя которого задается с командной строки. При этом, строка "#! /bin/bash" не должна удаляться.

Преобразование в HTML

Преобразуйте заданный текстовый файл в HTML формат. Этот сценарий должен автоматически вставлять необходимые теги HTML в тело файла.

Удаление тегов HTML

Удалите все теги HTML из заданного HTML файла, затем переформатируйте его так, чтобы строки не были короче 60 и длиннее 75 символов. Предусмотрите оформление параграфов. Преобразуйте таблицы HTML в их приблизительный текстовый эквивалент.

Преобразование XML файлов

Преобразуйте файл из формата XML в формат HTML и в простой текстовый файл.

Борьба со спамом

Напишите сценарий, который анализировал бы входящие почтовые сообщения на принадлежность к спаму и отыскивал бы в DNS имена узлов сети, по IP адресам из заголовка письма. Сценарий должен отправлять найденые спамерские сообщения ответственным за спам провайдерам (ISP). Естественно, вы должны отфильтровать свой собственный IP адрес, чтобы не случилось так, что вы жалуетесь на самого себя.

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

Азбука Морзе

Преобразуйте текстовый файл в код Морзе. Символы из файла должны быть представлены в виде, соответствующих им, кодов Морзе, состоящих из точек и тире, и разделенных пробелами. Например, "script" ===> "... _._. ._. .. .__. _".

Шестнадцатиричный дамп

Выведите, в виде шестнадцатиричного дампа, содержимое бинарного файла, передаваемого в сценарий, как аргумент командной строки. Вывод должен производиться в четкой табличной форме, первое поле таблицы -- адрес, далее должны следовать 8 полей, содержащие 4-х байтовые шестнадцатиричные числа, а завершать строку должно поле, содержащее эквивалентное отображение 8-ми предшествующих полей, в виде ASCII-символов.

Эмуляция сдвигового регистра

Используя Пример 25-9, как образец, напишите сценарий, который эмулировал бы 64-х битный сдвиговый регистр в виде массива. Реализуйте функции загрузки значения в регистр, сдвиг влево и сдвиг вправо. В заключение, напишите функцию, которая интерпретировала бы содержимое "регистра" как восемь 8-ми битных символов ASCII.

Детерминант (определитель)

Найдите детерминант (определитель) матрицы 4 x 4.

Анаграммы

Сценарий должен запросить у пользователя 4-х символьное слово, и найти анаграммы для этого слова. Например, анаграммы к слову word: do or rod row word. Для поиска анаграмм можете использовать файл /usr/share/dict/linux.words.

Индекс сложности текста

"Индекс сложности текста" оценивает трудность понимания текста, как некое число, которое грубо соответствует количеству лет обучения в общеобразовательной школе. Например, индекс равный 8-ми говорит о том, что текст доступен для понимания человеку, окончившему 8-й класс общеобразовательной школы.

Вычисление индекса ведется по следующему алгоритму.

  1. Выберите кусок текста, длиной не менее 100 слов.

  2. Сосчитайте количество предложений.

  3. Найдите среднее число слов в предложении.

    СРЕДНЕЕ_ЧИСЛО_СЛОВ = ОБЩЕЕ_ЧИСЛО_СЛОВ / ЧИСЛО_ПРЕДЛОЖЕНИЙ

  4. Сосчитайте количество "трудных" слов -- которые содержат не менее 3-х слогов. Разделите это число на общее количество слов, в результате вы получите пропорцию сложных слов.

    ПРОПОРЦИЯ_СЛОЖНЫХ_СЛОВ = ЧИСЛО_ДЛИННЫХ_СЛОВ / ОБЩЕЕ_ЧИСЛО_СЛОВ

  5. Индекс сложности текста рассчитывается как сумма двух этих чисел, умноженная на 0.4 и округленная до ближайшего целого.

    ИНДЕКС_СЛОЖНОСТИ = int ( 0.4 * ( СРЕДНЕЕ_ЧИСЛО_СЛОВ + ПРОПОРЦИЯ_СЛОЖНЫХ_СЛОВ ) )

4-й пункт -- самый сложный. Существуют различные алгоритмы подсчета слогов в словах. В данном же случае, вы можете ограничиться подсчетом сочетаний "гласный-согласный".

Строго говоря, при расчете индекса сложности не следует считать составные слова и имена собственные как "сложные" слова, но это слишком усложнит сценарий.

Вычисление числа пи по алгоритму "Игла Баффона"

В 18 веке, французский математик де Баффон (de Buffon) проделывал эксперимент, который заключался в бросании иглы, длиной "n", на деревянный пол, собраный из длинных и узких досок. Ширина всех досок пола одинакова и равна "d". Оказалось, что отношение общего числа бросков, к числу бросков, когда игла ложилась на щель, кратно числу пи.

Пользуясь Пример 12-35, напишите сценарий, который использовал бы метод Монте Карло для эмуляции "Иглы Баффона". Для простоты примите длину иглы раной ширине досок, n = d.

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

Шифрование по алгоритму Playfair

Напишите сценарий, реализующий алгоритм шифрования Playfair (Wheatstone).

В соответствии с этим алгоритмом, текст шифруется путем замены каждой 2-х символьной последовательности -- "диграммы". Традиционно, в качестве ключа, используется матрица символов алфавита 5 x 5.

   C O D E S
   A B F G H
   I K L M N
   P Q R T U
   V W X Y Z
            

            Матрица содержит все символы алфавита, за исключением
            символа "J", который представляет символ
            "I". Первая строка матрицы -- произвольно
            выбранное слово, в данном случае -- "CODES",
            далее следуют символы алфавита, исключая те, которые входят
            в состав первой строки.

Шифрование производится по следующему алгоритму: для начала, текст сообщения разбивается на диграммы (группы по 2 символа). Если в диграмму попадают два одинаковых символа, то второй символ удаляется, и формируется новая диграмма. Если в последней группе остается один символ, то такая "неполная" диграмма дополняется "пустым" символом, обычно "X".

THIS IS A TOP SECRET MESSAGE

TH IS IS AT OP SE CR ET ME SA GE
            

            Каждая диграмма может подпадать под одно из следующих
            определений:.

1) Оба символа находятся в одной строке ключа. Тогда, каждый из них заменяется символом, стоящим справа в той же строке. Если это последний символ строки ключа, то он заменяется первым символом в той же строке ключа.

2) Оба символа находятся в одном столбце ключа. Тогда каждый из них заменяется на символ, стоящий ниже, в этом же столбце. Если это последний символ в столбце ключа, то он заменяется первым символом в том же столбце ключа.

3) Символы диграммы стоят в вершинах прямоугольника. Тогда каждый из них заменяется символом из соседнего, по горизонтали, угла.

Диграмма "TH" соответствует 3-му определению.

G H
M N
T U           (Прямоугольник с вершинами "T" и "H")

T --> U
H --> G

            

            

Диграмма "SE" соответствует 1-му определению.

C O D E S     (Строка содержит оба символа "S" и "E")

S --> C  (замена на первый символ в строке ключа)
E --> S
            

            

Дешифрация выполняется обратной процедурой, для случаев 1 и 2 -- замена символом стоящим левее/выше. Для случая 3 -- аналогично шифрации, т.е. заменяется символом из соседнего, по горизонтали, угла. Helen Fouche Gaines, в своей классической работе "Elementary Cryptoanalysis" (1939), приводит подробное описание алгоритма Playfair и методы его реализации.

Этот сценарий должен иметь три основных раздела

  1. Генерация "ключевой матрицы", основывающейся на слове, которое вводит пользователь.

  2. Шифрование "плоского" текста сообщения.

  3. Дешифрование зашифрованного текста.

Широкое применение, в этом сценарии, найдут массивы и функции.

--

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