Сервант с кукушкой

В предыдущих публикациях я описал, как можно заставить комп пикать на манер «ку-ку» и как заставить его выбрасывать и затягивать лоток привода CDROM. таким образом, у нас остается один шаг до создания собственного «серванта с кукушкой».

Если кто не понял — некоторые админы «сервантом» называю сервер. Но у нас нет сервера, а название  мне понравилось — «Сервант с кукушкой» — звучит мега-аттрактивно! (Все равно-что «гроб с музыкой»!)

Итак,  что нам нужно сделать. Нам нужно научить комп двум вещам. Первая — научить его запускать программы по таймеру или точнее — по заданному времени. Вторая задача — научить комп циклически выполнять задачу определенное количество раз. Иначе говоря, ку-кукать столько раз, сколько показывают системные часы. А системные часы в Линуксе… О-о! Это великая вещь!

Они периодически синхронизируют свое время по сети с часами на всемирных серверах времени. А вы, наивный пользователь, удивлялись — почему в Линуксе так плохо с программами для установки времени. Вон, в Виндовсе как хочешь, так и ставишь время, и никаких проблем. Конечно, проблем никаких. Только вопрос, кому это надо — ставить неправильное время? Правильное время — оно одно у всех и для всех, только часовые пояса могут быть разные. И его можно и нужно получить автоматически с серверов времени. А всякие там подлоги с установкой времени в ручную — это все от Лукавого, только себя и обманываем.

Да и исторически так сложилось, что Виндовс развивалась как операционная система персонального компьютера, компьютера для одного пользователя. Комп изначально не был предназначен и не имел никаких связей с другими компами — никаких сетей и интернетов. А Unix и Интернет — это два брата-близнеца, которые выросли вместе. Следовательно, Linux-у (преемнику Unix) досталось по наследству все сетевое благополучие от предка.

Но ведь в Виндовсе тоже сетевая поддержка имеется? — Ну да, имеется. Только в Виндовсе это уже потом начали всё прикручивать и присопливливать к уже существующей парадигме ядра операционной системы. Поэтому у Майкрософта всё так коряво получилось, что изначально не было предусмотрено. К стати, до сих пор в Виндовсе все сетевые аспекты реализованы ужасно. Поговорите с системными программистами, кто пишет сетевой софт и вы столько интересного узнаете про Виндосовские сокеты… Поэтому-то и вирусня жрет Винду.

Однако, у нас Линукс, и наши часы периодически синхронизируются с мировыми сверх-точными часами. Ручная установка времени нам не нужна и не грозит. Мелочь, а приятно.

Как узнать сколько сейчас времени? — Да легко! Наберите команду:

$ date

На экране появится исчерпывающий ответ. Но нам надо знать только количество часов, остальное — лишнее. Поэтому давайте в команде зададим формат вывода:

$ date +%I

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

Таким образом, мы с вами плавно подошли к проблеме создания собственной программы. Но не пугайтесь! Программа не сложнее букварного выражения «мама мыла раму».

Для начала немного скучной теории.

Линукс условно делит файлы на две большие группы: файлы программ и файлы данных. В первых содержатся последовательности инструкций, выполняя которые можно достичь результата. А вторые… ну тут и говорить не о чем! Данные они и есть данные. Это то, что мы обычно обрабатываем, и в результате получаем другие данные.

Иначе говоря, файлы первого типа содержат «глаголы», файлы второго типа содержат «существительные». Поэтому первые могут выполняться, а вторые могут обрабатываться.

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

Исполняемые файлы второго вида прочитать и понять так просто не удастся — в них содержатся коды, которые понимает только микропроцессор. Для человека эти коды полная абра-кадабра. Но самое удивительное, что эта абра-кадабра получается из вполне читаемых (человеком) текстовых файлов путем их компиляции.

Помните, где-то в предыдущих публикациях мы видели странные последовательности буква типа -rwxr-xr-x. Так вот, буквочка «x» является ничем иным как признаком того, что этот файл можно исполнять, то есть этот файл — это есть программа! При создании программы с помощью компиляции исходного кода, компилятор сам устанавливает этот признак.

А вот при создании скрипта (это ведь обычный текстовый файл) эта задача ложиться на плечи пользователя, который создает скрипт. Другими словами, мы сначала пишем обычный текстовый файл, а затем с помощью специальной команды превращаем его в программу. При этом он всё равно остается текстовым. Но его уже можно будет выполнять. Лихо?

Собственно, чего долго ходить вокруг да около! Вот эта команда:

$ chmod +x my_proga

Здесь my_proga — это и есть тот самый текстовый файл, который мы превращаем в скрипт.

Если выполнить команду:

$ ls -l

до и после команды chmod, то можно увидеть разницу в изменении типа файла — наличие букв «x» говорит, что он стал исполняемым.

Итак давайте, напишем текстовый файл и превратим его в нашу первую программу. Но прежде всего, я предлагаю вам создать директорий для своих доморощенных программ. Пусть он по аналогии называется bin, и пусть размещается в нашем домашнем директории.

Последовательно выполняем команды:

http://www.ted.com/talks/view/lang/ru//id/884

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

Вторая команда — создает поддиректорий bin. Я предполагаю, что до этого момента у вас его не было. Если сомневаетесь, можете самостоятельно выполнить команду ls, и посмотреть что там у вас есть в домашнем директории.

Третья команда cd со странным параметром $! — это тоже команда смены директория. Вы, конечно, могли бы набрать cd bin, и получить тот же результат. Но я решил познакомить вас с еще одной фичей Линукса.

$! — это есть имя. Имя первого параметра предыдущей команды. Для нашего случая это есть bin. Да, bin — короткая последовательность символов, и набрать ее не составляет труда. Но в жизни иногда встречаются очень длинные и каверзные последовательности… В общем, не забывайте об этой фиче.

Итак, мы сейчас находимся в директории bin. Давайте создадим текстовый файл:

$ gedit qq.sh &

Эта команда запустит текстовый редактор gedit и скажет ему создать (или открыть, если существует) файл qq.sh. Значок амперсенда в конце команды позволит запустить редактор и вернуть управление в консоль. Таким образом мы можем независимо редактировать файл и производить другие операции в консоли.

Я напомню, что переключиться между консолью и редактором (точнее — между окнами на рабочем столе) можно с помощью комбинации Alt-Tab. Потренируйтесь, и это у вас начнет выполняться быстрее, чем мышко-перехватывание и мышко-тыкание.

В текстовом редакторе нам нужно набрать следующий текст:

#!/bin/bash
# Сервант с кукушкой

QQ=`date +%I`

while [ $QQ != "0" ]
do
  eject /dev/cdrom4
  beep -f 750 -l 200 -D 75 -r 1 -n -f 600 -l 180 -D 650 &
  eject -t /dev/cdrom4
  QQ=$(expr $QQ - "1")
done

Что тут есть и для чего.

Все строки, которые начинаются с символа решетки # — это комментарии. Это не команды, и они не исполняются. Если вам понадобится временно «выключить» какую-нибудь команду, просто закомментируйте ее.

Первая строка — это комментарий, но комментарий не совсем обычный. С помощью таких комментариев мы можем делать кое-какие подсказки системе. В частности, мы говорим, что для исполнения этого текста нужно запустить программу bash, которая находится в директории /bin. Этот директорий /bin — это не наш директорий! Наш bin располагается в нашем домашнем директории, абсолютный путь к нему будет примерно такой — /home/alex/bin/. Моя учетная запись alex, у вас, разумеется, будет что-то другое.

Следующая строка — это самый обычный комментарий. Можете написать в нем все что захотите.

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

Далее в программе мы определяем переменную QQ и присваиваем ей значение, которое будет получено в результате выполнения команды, которая заключена в обратные апострофы. О-о, как сказал! Иначе говоря, мы должны выполнить команду date +%I, а то, что она вернет, это присвоить переменной QQ. Забегая вперед скажу, что переменные в скриптах принято обозначать большими буквами. Привыкайте!

И поскольку мы с вами заговорили о переменных, то наверно мне следует сделать акцент на том, какие типы переменных допустимы в скриптах. Как это и печально, и иронично одновременно, но все переменные имеют единственно допустимый тип — строковый. Это ужасно. Это крайне неудобно. А если вы к тому же еще и мыслите о программировании скриптов с точки зрения языков программирования таких как Си или Паскаль, то разрыв мозга обеспечен!

Таким образом, что бы мы ни присвоили переменной, она это будет хранить как строку. Вот несколько простых примеров.

ALPHA=Clock
BETA="Сервант с кукушкой"
GAMMA=3.14159
PI="3.14159"

Здесь нет ни целочисленных, ни вещественных переменных. Здесь все переменные — строковые. Более того, переменные GAMMA и PI — имеют одинаковое значение. Отсутствие кавычек у числовой последовательности не приведет ее к интерпретации как числа. Последовательность символов как была строкой, так строкой и останется. Это не Си и не Паскаль. Здесь рулят другие законы.

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

А ведь мы как раз в своем «серванте» должны организовать подсчет ку-куканий. Как это сделаем, читайте далее.

Итак, в нашей переменной QQ содержится число (точнее — строка символов, состоящая из цифр), равное количеству повторений для цикла. Теперь мы должны организовать сам цикл. Для этого мы используем оператор цикла, который выглядит так:

while [ условие ]
do
  тело цикла
done

Цикл будет повторяться по кругу до тех пор, пока условие будет истинно. На каждом круге, цикл будет выполнять тело. Тело цикла — это набор (или последовательность) команд.

Наше условие записано так $QQ != «0». В этом выражении берется значение (строковой) переменной QQ и сравнивается со константной строкой, состоящей всего из одного символа — нуля. Условие считается истинным, если значение переменной QQ будет будет отличаться от строки «0». Как только QQ станет равной «0», условие станет ложным и цикл прервется.

Хорошо. Теперь, посмотрите на последнюю строку в теле цикла. Ага! Тут что-то происходит с переменной QQ. Она тут как-то изменяется.

С одной стороны понятно, что тут происходит уменьшение значения переменной QQ на единицу. Но как!? Как можно к строковой переменной применить арифметические операции? Ответ простой — никак!

Поэтому, используется специальная команда expr. (Вообще-то expr — это утилита (программа), которая находится в директории /usr/bin.) На вход ей подаются аргументы (разумеется — строковые) . Одни аргументы она конвертирует в числа, другие пытается понять как действия, которые необходимо совершить над этими числами.

После того как утилита вычислит ответ (число), она выдаст его на стандартное устройство вывода — то есть в консоль. Вывод на консоль всегда текстовый. Иначе говоря, мы снова получим число в виде строки символов.

А теперь, у вас наверняка закипят мозги: «Какая нафиг консоль!» Все правильно! До консоли строка не дойдет. Вы видите вокруг команды круглые скобки и знак доллара? Вот эта конструкция не только вызовет на исполнение утилиту expr с аргументами, но еще и перехватит вывод этой утилиты и передаст его переменной QQ.

О-о, как!

Таким образом, на каждом круге (программисты говорят — на каждой итерации) происходит уменьшение переменной QQ. И когда она станет равна нулю, условие окажется ложным и цикл прервется. Что нам и надо!

Остальные три команды, которые находятся в теле цикла, я не буду объяснять. Вы и так их уже знаете из предыдущих публикаций. Единственное, разве-что упомяну, это — в вашей системе CDROM может называться как-то по другому. Не ошибитесь с именем.

Теперь давайте сохраним набранный (или закопипасченный ?) текст. Только не хватайтесь за грызуна! Нажмите Ctrl-S. А потом переключитесь на консоль — Alt-Tab. Привыкайте выполнять действия по-Линуксовому, а не по-Виндовому. Это на самом деле не сложно (потренироваться только надо) и реально намного быстрее, чем прицеливаться мышкой в пункты меню.

В окне консоли наберите команду ls -l и убедитесь, что у вас есть файл qq.sh. Заметьте, что это пока всего-лишь текстовый файл.

Можете набрать команду:

$ file qq.sh

и система вам расскажет, что это за файл.

А теперь давайте превратим его в программный скрипт:

$ chmod +x qq.sh

И еще раз наберите команды ls и file. Посмотрите, что произошло.

Скрипт готов, можно испытать. Запускаем:

$ ./qq.sh

Ну как, получилось?

Теперь решаем вторую задачу — учим комп запускать программы согласно заданному времени.

В Линуксе имеется три штатные команды, которые могут выполнять заданные действия в указанное время:

  • watch   — выполнять программу через заданные промежутки времени;
  • at      — назначить задание на одноразовое выполнение в заданное время в будущем;
  • crontab — назначить задание на многоразовое выполнение в будущем

Какая на ваш взгляд из них нам больше всего подходит? — Конечно же crontab!

Команда crontab периодически, раз в минуту заглядывает в директорий /var/spool/cron/crontabs/, считывает оттуда файл заданий, просматривает и запускает те задания, которые соответствуют текущему времени.

Для задания crontab-у запланированных действий нужно выполнить команду:

$ sudo crontab -e

Откроется текстовый консольный редактор и на экране появится текст-заготовка. От нас требуется в самом низу текста набрать только одну строку:

0 */1 * * * /home/alex/bin/qq.sh

Структура записи сложна только на первый взгляд, на самом деле тут все просто. В начале идут пять полей для указания времени, когда должна сработать «часовая бомба». Последнее шестое поле — собственно, запускаемая команда.

Поля задания времени располагаются в нелогичной последовательности,  но с этим можно смириться. Вот из последовательность:

Минута Час Деньмесяца Месяц Деньнедели

Если не имеет значения в какой месяц, или в какой день, или в какой час должна выполняться команда, то в этом поле устанавливаем звездочку *. А если имеет, то указываем конкретное значение. Например, нас интересует выскакивание кукушки только в ноль-ноль минут, поэтому мы указываем в первом поле цифру 0.

Втрое поле (поле часов) понять несколько сложнее. Звездочка говорит, что нас не интересует какой-то конкретный час. Нас интересует срабатывание каждый час — это символы /1. Если нам нужно, чтобы команда срабатывала через каждые три часа, мы должны указать /3. Ну и так далее.

Ну вот, собственно это всё! Только когда будете выходить из текстового редактора, не забудьте сохранить crontab.

Да! И вот еще что. Не забывайте, что у вас в системе может быть не установлен модуль динамика pcspkr, в результате вы не получите желанного «ку-ку». Как его установить, читайте здесь:

https://zhevak.wordpress.com/2012/01/08/ку-ку/

Реклама

2 responses to “Сервант с кукушкой

  1. Настоящая кукушка должна кричать «Ordnung und arbeiten!»

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s