Сумасшедшие идеи настоящих гиков: использование стандартных утилит для решения нестандартных задачПриверженцы UNIX-систем не просто пользователи, это люди с пытливым умом, любовью к велосипедостроению и непреодолимым желанием доказать свою гиковость. Они готовы потратить не один час свободного времени, чтобы найти нетривиальное решение простой проблемы или доказательство возможности ее решения с помощью не предназначенных для этого средств. И все это ради удовольствия. HTTP-сервер своими рукамиМиниатюрный HTTP-сервер, собранный из подручных компонентов, остается одной из самых любимых тем современных гиков. Они готовы написать его буквально на всем, начиная от простого использования команды netcat на 80-порту и закачивая языком PostScript, используемым для форматирования текста перед выводом на принтер. Блоггер по имени Алексей Свечников взялся за эту тему и написал HTTP-сервер на bash размером всего 222 байта (http://alexey.sveshnikov.ru/blog/2006/12/23/http-сервер-размером-в-222-байта/). Сначала вся идея сводилась к горячо любимому UNIX-админами рудиментарному серверу с использованием nc, пример которого приведен ниже:
Но затем пример оброс функционалом и превратился в HTTP-сервер, способный отдавать файлы по запросу и список файлов текущего каталога. Ниже приведена переработанная версия скрипта Алексея, которая корректно работает с google chrome и избавлена от бага с файлами, имеющими в названии символы в верхнем регистре:
Все это одна команда. Сервер отдает файлы текущего каталога, для запроса списка которых достаточно просто обратиться к корневому каталогу. После выбора файла добавляем его имя в адресную строку и благополучно скачиваем на свою машину. Некоторое время спустя Алексей реализовал более продвинутую версию сервера, которая умеет отдавать HTTP-заголовки (а для файлов вместе с размером и MIME-типом), обрабатывает ошибку 404 и отдает полноценный index.html. Ее однострочный оригинал и развернутый вариант, удобный для чтения и анализа, ты найдешь на прилагаемом к журналу диске. Еще более гиковый вариант HTTP-сервера имеется на страничке Martin A. Godisch. Он пошел дальше всех остальных и воспользовался для написания сервера не каким-нибудь bash или awk, а языком программирования PostScript, который был разработан Adobe Systems для описания сложных графических объектов и подготовки печатных изданий. Исходный текст сервера слишком велик, чтобы продемонстрировать его на страницах журнала, но ты можешь получить его, обратившись к страничке http://people.debian.org/~godisch/pshttpd или заглянув внутрь нашего диска. Демон закачек на базе CUPSМенеджер печати CUPS, ставший стандартом в UNIX-системах, обладает несколькими очень привлекательными характеристиками, которые позволяют использовать его в качестве менеджера любых очередей, к которым необходим удаленный доступ и расстановка приоритетов. Если в твоем распоряжении имеется машина, которую ты собираешься использовать для закачки файлов, то CUPS позволит ей справиться с этой задачей без необходимости установки дополнительного софта и танцев с бубном. Алгоритм действий по превращению CUPS в демон закачек следующий: 1. Для начала напишем скрипт cwget.sh, который будет осуществлять закачку файлов и вызываться приведенным ниже CUPS-бэкендом:
Сделаем его исполняемым:
2. Теперь создадим специальный CUPS-бэкенд, который будет принимать добавленные в очередь URL и отдавать их вышеописанному скрипту:
Дадим ему права на исполнение:
3. Чтобы позволить коду бэкенда использовать sudo для запуска скрипта cwget.sh с рутовыми полномочиями, разрешим пользователю lp, с правами которого запускаются CUPS-задания, делать это без запроса пароля:
4. Настроим несколько принтеров через web-интерфейс, указав в качестве их бэкенда cwget (смотри скриншот «Виртуальные принтеры с cwget-бэкендом») и объединим их в класс, чтобы получить возможность одновременной закачки более чем одного файла. 5. Все, теперь можно отсылать задания (URL) на виртуальный принтер. Сделать это можно, например, так: Openbsd и безопасный голосовой чат из коробкиOpen'овская утилита aucat, изначально созданная для проигрывания «сырых» звуковых файлов с расширением .au, со временем обросла функциональностью и сегодня может использоваться для многих целей, включая различные преобразования звукового потока в режиме реального времени, а также возможность применения в качестве полноценного аудиосервера, способного смешивать звуковые потоки, порождаемые другими инстанциями aucat. Известный в OpenBSD-кругах хакер по имени Райан Флэнири воспользовался этой возможностью для создания простой системы голосового чата, не требующей установки какого-либо дополнительного ПО. Идея, положенная в ее основу, такова: 1. Запустить aucat в режиме сервера на двух удаленных машинах. Работая в режиме сервера, aucat подключится к устройствам ввода и вывода звука и создаст UNIX-сокет, чтение из которого приведет к чтению данных из устройства ввода (микрофон), а запись — к записи в устройство вывода (колонки). 2. Запустить второй процесс aucat в обычном режиме на первой машине и перенаправить его вывод процессу aucat, работающему на второй машине с помощью ssh. В результате входной поток, полученный с микрофона и направленный сервером aucat в UNIX-сокет, будет прочитан aucat-процессом и перенаправлен на удаленную машину, где его прочитает удаленный aucat-процесс и запишет в UNIX-сокет собственного aucat-сервера. Так звук с микрофона первой машины попадет в колонки второй. 3. Повторить шаг 2 на второй машине, чтобы создать обратную связь. На уровне командной строки все это выглядит так:
Однако именно в таком виде система не заведется. Оказывается, работая в серверном режиме, aucat привязывает создаваемый UNIXсокет к запустившему его пользователю (файл получает имя /tmp/aucat-ID-юзера/default), и когда клиентский процесс aucat подключается к серверу, он также использует ID текущего пользователя для обращения к сокету. Чтобы работать совместно, сервер и клиент aucat должны быть запущены одним пользователем. В приведенном выше примере клиент aucat, запускаемый на машине host2 с помощью ssh, будет работать с правами пользователя user1, тогда как сервер на этой машине будет запущен с правами пользователя user2, поэтому звук до второй машины «не дойдет». Для этого, можно либо использовать аккаунты с одинаковым ID пользователя на обеих машинах, либо пойти на небольшой трюк и после запуска сервера создать ссылку на каталог /tmp/aucat-ID-юзера для другого пользователя. Вот как это сделать на обеих машинах:
Затем можно запускать перенаправление звука. Райан предостерегает, что по умолчанию ты получишь слишком большую задержку, и рекомендует установить минимальный размер буфера и снизить частоту дискретизации звукового потока до 11000 Гц:
Видеопамять как свопСовременные графические адаптеры оснащаются внушительным объемом высокоскоростной памяти, большая часть которой остается незадействованной во время обычной работы с системой. Ядро Linux позволяет использовать эту память для своих нужд, зарезервировав небольшой ее объем для стандартных VESAрежимов, а все остальное использовать для хранения файлов или создания своп-раздела. Проделать такое можно с помощью специального драйвера под названием Memory Technology Device (MTD), позволяющего адресовать не только оперативную память, но и память любого устройства, подключенного через шину PCI. Вся методика сводится к активации драйвера в ядре, выяснению адресного пространства видеопамяти и ее отображения в адресное пространство ядра. Итак, для начала активируем драйвер в ядре, для этого запустим «make menuconfig», перейдем в раздел Device Drivers и активируем следующие пункты меню:
Теперь необходимо найти видеопамять в адресном пространстве шины PCI. Для этого воспользуемся утилитой lspci и найдем графический адаптер:
Вывод должен выглядеть примерно так:
Узнаем детальную информацию о карточке:
Видеопамять разделена на несколько регионов, один из которых помечен как prefetcheble. Это и есть основное место хранения изображений, формируемых адаптером для вывода на экран (буфер кадров), а также для хранения промежуточных результатов обработки 3D-изображений. Проведя небольшие расчеты, мы можем выяснить, какая ее часть используется под буфер кадров, необходимый для вывода 2D-картинки на экран (которой мы пожертвовать не можем, не потеряв возможность работать с графикой), а какая применяется только для расчетов в режиме 3D и потому может быть использована нами. Изображение, хранимое в буфере кадров, представляет собой двумерный массив, размер которого соответствует используемому разрешению экрана, а размер каждого элемента равен глубине цвета. Поэтому при разрешении экрана 1024x768@32 для хранения изображения будет задействовано 1024 * 768 * 4 = 3145728 байт (32 бита = 4 байта) или 3 Мб. Как и любой другой процессор, видеочип адресует память от ее начала, поэтому, чтобы получить доступ к видеопамяти, не задев при этом буфер кадров, мы должны отобразить память не от ее начала, а с точки, расположенной за этими самыми тремя мегабайтами (а лучше сразу за восемью для надежности и поддержки более высоких разрешений). Берем из вывода приведенной выше команды lspci адрес prefetcheble-региона видеопамяти. Он указан после словосочетания «Memory at» и в нашем примере составляет e0000000. Переводим 8 Мб в шестнадцатиричную систему счисления и получаем 800000. Прибавляем это число к адресу региона и получаем e0800000. Далее выходим из иксов и подгружаем модуль phram, передав ему в качестве аргументов этот адрес и размер региона (если адаптер оснащен 128 Мб памяти, то размер за вычетом 8 Мб будет равен 120 Мб):
Проверяем наличие псевдоустройства MTD:
В выводе должен быть указан размер устройства, начало адресуемой им памяти и его имя. Если все в порядке, загружаем модуль mtdblock, который превратит псевдоустройство /dev/mtd0 в блочное устройство /dev/mtdblock0:
Это все, теперь на устройстве можно создать своп:
Или файловую систему:
Чтобы не обрушить иксы, открой конфиг /etc/X11/xorg.conf и вставь в секцию Device строку Driver "vesa". Тетрис, Арканоид и Сокобан из редактораПотоковый редактор SED (Stream EDitor), существующий в UNIX с начала времен и предназначенный для потокового неинтерактивного редактирования текстов с помощью управляющих команд, оказался настолько мощным инструментом, что с его помощью можно не только выполнять сложнейшее редактирование текста, но даже написать полноценное приложение или целую игру. Наверное, все слышали облетевшую многие UNIX-сайты и блоги историю о том, как девушка по имени Юля написала самый настоящий тетрис, используя только редактор SED и небольшой скрипт-обертку (http://uuner.livejournal.com/55238.html). Трудно сказать, что побудило ее на эту странность, однако содержащийся в представленных файлах код взрывает голову, начиная уже с первых строк, и говорит о незаурядном мышлении и превосходном знании редактора. Однако, как бы это не било по гордости за родную отчизну, на официальном сайте редактора (http://sed.sourceforge.net) подобных игр насчитывается аж 11 штук, среди которых можно найти такую классику как сокобан и арканоид, работающий в пошаговом режиме. А если промотать ниже, то найдешь даже модуль для Apache, позволяющий исполнять SED-сценарии внутри web-сервера. Jabber вместо SSHВозможность воспользоваться полноценным SSH-доступом есть далеко не всегда. Машина может находиться за файерволом, который режет 22-й порт, или входить в частную сеть с доступом в интернет только через NAT. Приходится включать творческое мышление, и первое, что приходит в голову — написать простой jabber-бот, который будет подключаться к jabber-серверу, слушать вводимые другим пользователем команды и выполнять в окружении операционной системы. Немного поискав в Сети, мы обнаружим, что идея не нова, и некоторые люди уже пробовали создать нечто подобное. Мне понравилась реализация, написанная командой сайта www.ylsoftware.com. Наибольшая ее ценность в простоте исходника бота, который легко понять и модифицировать для своих нужд.
Бот регистрируется на сервере под отдельным JID'ом (который придется завести заранее) и принимает команды только от пользователей, перечисленных в опции admins. Теперь можно установить зависимости в виде пакетов perl, libnet-xmppperl и libnet-jabber-perl и запустить бота: Сообщения от запускаемых тобой команд будут приходить в ответных сообщениях. Web-камера в качестве мышиВведя в адресной строке браузера строку www.youtube.com/watch?v=LG HItQK2fA8&feature=player_embedded, ты сможешь увидеть видеоролик, демонстрирующий работу небольшого python-скрипта, позволяющего управлять курсором мыши с помощью любых объектов, находящихся в зоне видимости web-камеры. На нашем диске ты найдешь скрипт, который позволяет это делать. Для его запуска потребуется установить пакеты cmake, python, python-xlib, а также самый важный компонент — библиотеку компьютерного зрения OpenCV (http://opencv.sf.net). Ее нет в большинстве дистрибутивов, поэтому придется собрать самостоятельно: После установки всех компонентов просто запусти cam-mouse-ctrl.py, и ты сможешь проделать трюк, показанный в ролике. А что сделал ты?Все описанные в статье приемы были придуманы такими же юниксоидами, как ты. Если в твоей голове есть другие интересные идеи нестандартного использования программ или даже их полноценные реализации — смело шли их мне, и если они окажутся достойны внимания, мы опишем их в одной из ближайших статей (не забыв о копирайтах :). Links
InfoPostScript — язык описания страниц. Предназначен для формирования изображений произвольной сложности и вывода их на печать. |