28 октября 2007

Про rm

Ситуация. Я, не вполне проснувшийся после обеда, сажусь к компу. Происходит такой диалог:
[15:04:04] <Andron> помощь нужна,
[15:04:56] <Andron> есть каталог в нём накопилось дофига файлов, около 11тыс., нужно их грохнуть
[15:05:11] <Andron> ...но:
[15:06:03] <Andron> делаю: rm -f ./*
а он мне: bash: /bin/rm: Argument list too long
и нифига не удаляет :(
[15:06:04] <leonid.phoenix> рм ругается, что аргументов много?
[15:06:14] <leonid.phoenix> а, ну вот.
[15:06:36] <leonid.phoenix> да всяко можно сделать
[15:06:59] <leonid.phoenix> rm `ls | head -n 1000`
[15:07:18] <leonid.phoenix> и так 11 раз
[15:11:59] <Andron> спасибо!!!
[15:12:02] <Andron> помогло!!!
Интересно тут несколько моментов. На такие вещи я напарывался хоть и очень редко, но бывало, и каждый раз изобретал какой-нибудь новый велосипед. Тут же спросонья выдал один из самых коротких и простых. Ну цикл ещё можно было бы прикрутить, например, так:

while (rm `/bin/ls| head -n 1000`);do done;

О природе мэшапов.

Столкнулся с таким понятием как мэшап (примеров им - легион, довольно часто освещаются Интернетными Штучками). И чем больше вникал в суть явления, тем более знакомым оно мне казалось. Наконец я понял, что же именно так знакомо в этом.
Мэшапы - типичный пример Unix-way, перенесённый в несколько другую сферу. Берём контент с одного сервиса. пропускаем через несколько пайпов - voila, перед нами новый сервис, обладающий синергией. Существенное отличие от привычного Unix-way в том, что контент далеко не всегда plain text.

26 октября 2007

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

По мотивам поста.
Мне вообще кажется, что для распространения практически любого контента торренты гораздо удобнее стандартных http и ftp и имеют много преимуществ помимо описанного в посте.
Несколько примеров.
Если бы убунту не распространялась ещё и через торрент, я думаю, все её сервера не выдержали бы такого DDoS'а со стороны её же добрых пользователей.
Майкрософт разрабатывает свой протокол передачи данных (сильно похожий на торренты, но всё же свой).
Появляются торрент-комбайны, например, ориентированный на мультимедиа контент Vuze , брат одного из популярных торрент-клиентов Azureus. Имхо, эта область - мультимедиа вещание в сети - первый кандидат на освоение торрентов.

10 октября 2007

Кпк + Bluetooth + Linux box

В наше время всё больше ценится мобильность. Соответственно, всё большее распространение получают всевозможные мобильные устройства вроде смартфонов, наладонников и коммуникаторов. И одним из важных достоинств этих устройств является возможность выхода в сеть из любой точки делового маршрута. И смартфоны и коммуникаторы решают этот вопрос с помощью GPRS, простые наладонники без GSM модуля могут использовать сотовый телефон. Но иногда бывает целесообразнее использовать существующее высокоскоростное стационарное подключение одного из рабочих мест. Да и доступ к внутренней сети дома или офиса иногда бывает необходим. И в связывании рабочей станции и наладонника без проводов нам поможет Bluetooth.

Итак, вводные данные. Bluetooth адаптер, КПК под одной из разновидностей Windows mobile и стационарная рабочая станция с Linux на борту. В моём случае это USB Bluetooth брелок, HP iPAQ под управлением Win Mobile 2003 и Gentoo 2006.1.

Понадобятся пакеты bluez-libs, bluez-utils, iptables, ppp. Устанавливаем. Если ядро собрано самостоятельно - включаем в нём Networking -- Bluetooth subsystem support и всё нижележащее, также не забываем включить iptables и поддержку цели MASQUERADE в нём (Networking -- Networking options--Network packet filtering (replaces ipchains) -- IP: Netfilter Configuration -- MASQUERADE target support). Записываем в /etc/bluetooth/pin какое-нибудь число (будет применяться для подтверждения соединения, нам не важно). Редактируем /etc/bluetooth/rfcomm.conf, дабы он принял примерно такой вид:

rfcomm0
{
# автоматически биндить устройство при запуске
bind yes;
# MAC должен быть закомментирован
#
# device 11:22:33:44:55:66;
#
# RFCOMM канал для соединения
channel 2;
#Метка
comment "Bluetooth Access Point";
}


Если у вас запущены какие-то Bluetooth-сервисы, то правильно выберите канал, он должен быть уникальным. Для удобства можно зайти в /etc/bluetooth/hcid.conf и изменить name на что-то более понятное, например так:

name "BlueZ Access Point at %h";

чтобы не путать соединения с разными машинами, к которым вы будете подключаться.

Теперь /etc/ppp/options. У меня он был почти пуст. Добавляем (или меняем соотв. значения):

noauth
ms-dns 216.148.227.62
ms-dns 204.127.202.2

где IP - IP вашего DNS сервера (можно скопировать из /etc/resolv.conf)

На этом единовременные подготовления Большого Брата закончены. Теперь действия, которые должны быть выполнены при загрузке системы. Я оформил это в виде rc скрипта для своей системы, если же у вас sys V init (стиль скриптов загрузки, используемый в большинстве образованных от Redhat дистрибувов), замените его на аналогичный sh скрипт, убрав из него функцию depend и вызовы ebegin и eend.

#!/sbin/runscript

depend() {
use net
use iptables
after sshd
after bluetooth
after logger }

start() {
#modprobe rfcomm
#modprobe hci_usb
ebegin "Starting btlan"
[ -a /dev/rfcomm0 ]|| mknod /dev/rfcomm0 c 216 0
[ -a /dev/rfcomm1 ]|| mknod /dev/rfcomm1 c 216 1
[ -a /dev/rfcomm2 ]|| mknod /dev/rfcomm2 c 216 2
[ -a /dev/rfcomm3 ]|| mknod /dev/rfcomm3 c 216 3

hciconfig hci0 up
hcid
sdptool add SP
sdpd
rfcomm bind all
dund --listen --msdun --channel 2 10.20.4.89:10.0.0.111
echo '1' &gt; /proc/sys/net/ipv4/ip_forward
# use a different ppp0 name if your server's incoming
#internet connection is coming from a different device
#(e.g. might be sit0 or ppp1, depending how your Linux is connected to the outside world).
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
iptables -A FORWARD -i ppp1 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
eend 0
}

stop() {
ebegin "Stopping btlan"
killall dund
rfcomm release all
killall sdpd
sdptool del SP
killall hcid
hciconfig hci0 down
[ -a /dev/rfcomm0 ]&& rm -f /dev/rfcomm0
[ -a /dev/rfcomm1 ]&& rm -f /dev/rfcomm1
[ -a /dev/rfcomm2 ]&& rm -f /dev/rfcomm2
[ -a /dev/rfcomm3 ]&& rm -f /dev/rfcomm3

eend 0 }

Несколько комментариев. У меня всё, касающееся Bluetooth было вкомпилировано в ядро, поэтому запуск modprobe для загрузки нужных модулей мне был не нужен. Возможно, вам потребуется загрузить и другие модули. В вызове dund первый IP - мой внутренний IP сети провайдера, получаемый по DHCP. Второй - будущий IP КПК. В первом вызове iptables интерфейс ppp0 заменяется на тот, с которого ваш Linux box получает интернет. Во втором вызове - ppp1 заменяется на первый незанятый ppp интерфейс.

Обратите внимание на функцию depend. Её запись означает, что данный скрипт требует работающей сети, iptables, sshd (как одно из возможных применений - в качестве пульта дистанционного управления ББ, вам, возможно, не понадобится) и после запуска служб bluetooth и журналирования. Исходя из этого, определите место для данного скрипта в вашей системе инициализации. Теперь при загрузки система будет предоставлять Bluetooth соединение. Если же вы носите Bluetooth брелок с собой, то можно настроить и автоматическое подключение устройства и создание Bluetooth сети, за это будет отвечать udev. Например у меня в директории /etc/udev/rules.d было установлено правило 70-bluetooth.rules, которое ссылалось на выполняемый при под- и отключении Bluetooth устройств скрипт:

KERNEL=="hci[0-9]*", RUN+="/lib/udev/bluetooth.sh"

который проверяет, подключили или отключили устройство и инициализирует его (добавленные мною строки заканчиваются пустым комментарием):

#!/bin/sh
#
# bluetooth.sh: udev external RUN script
#
# Copyright 2005-2006 Henrik Brix Andersen
# Distributed under the terms of the GNU General Public License v2

script=/etc/init.d/bluetooth
btlan=/etc/init.d/btlan #

# Find out where sysfs is mounted. Exit if not available
sysfs=`grep -F sysfs /proc/mounts | awk '{print $2}'`
if [ "$sysfs" = "" ]; then
echo "sysfs is required"
exit 1
fi

if [ ! -d $sysfs/class/bluetooth/hci[0-9]* ]; then
if $script --quiet status; then
$btlan stop #
$script stop
fi
else
if ! $script --quiet status; then
$script start
$btlan start #
fi
fi

Настройка клиента проста. Включаем Bluetooth, запускаем Bluetooth менеджер, создаём новое соединение, выбираем Explore bluetooth device, там выбираем свою точку доступа, среди предоставляемых ей сервисов выбираем LAN Acces Point. В Bluetooth менеджере создаётся ярлык. Запускаем. Предлагается ввести логин и пароль, оставляем пустыми все поля. Вы в сети.
Когда я покупал Bluetooth брелок, на коробочке с ним было гордо написано: "Built for Mac OS X" и "Designed for Microsoft Windows XP". И знаете что? Я её выкинул. Потому что поставляемым с брелоком ПО, достаточно неплохим, должен отметить, я аналогичного функционала добиться не смог.

Vim like zsh keymapping


Данная статья посвящена исключительно настройке клавиатурных привязок в zsh в стиле vim, во избежание повторений общих советов в статье нет.

В одном из обзоров редактора vim я встретил фразу, смысл которой сводится к следующему - очень многое в UNIX основано на подобии, поэтому изучение данного редактора для относительно опытного пользователя не должно представлять трудности.
Многие разработчики отталкиваются от этого подобия и делают приложения чем-то похожими либо на vim, либо на emacs, либо на оба редактора. Именно так поступили создатели zsh, предоставив пользователю на выбор четыре схемы "привязок горячих клавиш" для редактора коандной строки - emacs, viins, vicmd и .safe (две схемы для vim для эмуляции разных его режимов).
Я люблю vim и постоянно использую его и только его, под какой бы операционной системой ни оказался, благо его порты есть под самую разнообразную экзотику. И в ходе очередного витка изысканий по настройке zsh было принято решение - для эффективности и унификации использовать схему привязок vim. Однако чувство незаконченности и неудобства не покидало меня. И выход был найден - создать свои схемы привязок на основе уже существующих, воспользовавшись поистине безграничными возможностями настройки zsh.
Итак, открываем ~/.zshrc.

1. Создадим две схемы на основе существующих (по одной на режим вставки и командный):

#vi insert mode like keybindings
#defining something more usable than the defaults vi bindings
#creating two keymaps
bindkey -N myviins viins
bindkey -N myvicmd vicmd

2. Исправим досадное недоразумение - zsh никак не отображает текущий режим - напишем свои переключения:

#defining widgets, to switch between them
function my_viins_to_vicmd(){print -n "\033]0;zsh\a";bindkey -A myvicmd main}
function my_vicmd_to_viinsi(){print -n "\033]0;zsh INSERT\a";bindkey -A myviins main}
function my_vicmd_to_viinsa(){print -n "\033]0;zsh INSERT\a";zle vi-forward-char;bindkey -A myviins main}
zle -N my_viins_to_vicmd
zle -N my_vicmd_to_viinsi
zle -N my_vicmd_to_viinsa
bindkey -M myviins '^[' my_viins_to_vicmd
bindkey -M myvicmd 'i' my_vicmd_to_viinsi
bindkey -M myvicmd 'a' my_vicmd_to_viinsa

Теперь в заголовке эмулятора терминала будет отображаться режим вставки.

3. Небольшая полезняшка - памятка с текущими привязками:

function list_mappings(){bindkey}; zle -N list_mappings
bindkey -M myvicmd ':map' list_mappings

4. сделаем свой режим вставки режимом по умолчанию:

#setting my vi-like insert mode by default
bindkey -A myviins main

5. Исправим непривычное поведение некоторых клавиш (адаптация общего совета Алексея Федорчука)

#making work some special keys
bindkey "\e[2~" yank
bindkey "\e[3~" delete-char
bindkey "\e[5~" up-line-or-history
bindkey "\e[6~" down-line-or-history
bindkey "\e[A" up-line-or-search ## up arrow for back-history-search
bindkey "\e[B" down-line-or-search ## down arrow for fwd-history-search

#making work Home and End keys in both modes
case $TERM in
linux)
bindkey -M myviins "\e[1~" beginning-of-line
bindkey -M myviins "\e[4~" end-of-line
bindkey -M myvicmd "^[[1~" beginning-of-line
bindkey -M myvicmd "^[[4~" end-of-line
;;
*xterm*|rxvt|(dt|k|E)term)
bindkey -M myviins "\e[H" beginning-of-line
bindkey -M myviins "\e[F" end-of-line
bindkey -M myvicmd "\e[H" beginning-of-line
bindkey -M myvicmd "\e[F" end-of-line
;;
esac

Ну и напоследок небольшой пример, показывающий, как писать виджеты ("задача виджета выполнять некое малое действие") в стиле команд vim и привязывать их к клавиатурным сочетаниям.
Иногда возникает потребность быстро заменить один из аргументов в вызове программы:

kill -HUP foobar
kill -9 foobar

это и будет делать мой виджет.
Сначала объявляем функцию, которая будет это делать:

#simple widget, wich deletes N-th parameter (word) in line
killparam()
{
zle beginning-of-line
zle vi-forward-word -n ${NUMERIC:-1}
zle delete-word -n 1
zle vi-delete-char -n 1
zle my_vicmd_to_viinsi
}

затем провозглашаем её виджетом:

zle -N killparam

и привязываем к горячей клавише:

bindkey -M myvicmd 'k' killparam

При написании виджета для простоты я использовал только уже готовые виджеты самой zsh, вызывая их с помощью команды zle. Обратите внимание на передачу параметра второму из них - если $NUMERIC не определён, будет передана еденица. Всем остальным виджетам предписано выполняться строго один раз, даже если $NUMERIC задан (-n 1).
Теперь, чтобы удалить -HUP в указанном примере достаточно в режиме редактирования набрать 1k или просто k ( если набрать 2k, то будет удалено второе слово и так далее).
Таким образом я избавился от неинформативности оболочки, странного поведения привычных вещей и научил её выполнять новые трюки.

Два колеса и пять педалей - катаемся на нестандартных мышках


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

Прежде всего мы должны убедиться, что X сервер правильно работает с мышкой. Вопросы использования мышек в консоли оставим эстетам, не разделяющим моего мнения о том, что мышка в консоли вообще явление необязательное, тем более такая. Рассмотренная конфигурация - Xorg 7.x, A4 tech WOP-49 (5 нажимаемых кнопок включая одно из колёс, 2 колеса).
Отправляемся в xorg.conf и в соответствующей секции вносим изменения:

Option "Protocol" "ExplorerPS/2"
Option "Buttons" "9"
Option "ButtonMapping" "1 2 3 8 9"
Option "ZAxisMapping" "4 5 6 7"

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

Option "ButtonMapping" "1 2 3 6 7"
Option "ZAxisMapping" "4 5"

Итак, все манипуляции с мышью, кроме перемещения, X сервер воспринимает как нажатия кнопок. Соответственно, в моём случае 1,2,3,8,9 обозначают левую, среднюю, правую и две боковые кнопки, а 4,5,6,7 - движения колёс. И именно нажатиями кнопок я буду всё это называть для унификации в дальнейшем.

Запускаем X сервер и убеждаемся, что всё работает правильно. Можно покрутить какой-нибудь документ в книжной ориентации в обоих направлениях. Но окончательный вердикт вынесет утилита xev. При получении каких либо событий она отправляет их описание в консоль. И если на нажатия боковых кнопок в её выводе присутствует button 8 и button 9 (6 и 7 для одноколёсной мыши), значит, всё нормально и кнопки видны X серверу.

Следующая задача - получить возможность назначать произвольное действие боковым (в принципе - любым) кнопкам, по возможности - штатными средствами самих приложений. Очень напоминает горячие клавиши, не так ли? Основная идея в этом и состоит - эмулировать нажатие комбинации клавиш при нажатии кнопки мыши. В дальнейшем мы можем назначить ей в каждом приложении своё действие.

Для этого нам понадобятся xbindkeys и xvkbd из одноименных пакетов. Вся магия будет совершаться при помощи следующих строк в ~/.xbindkeysrc:

"xvkbd -xsendevent -text "\[Control_L]\[KP_Divide]""
b:8
"xvkbd -xsendevent -text "\[Control_L]\[KP_Multiply]""
b:9

То есть боковые кнопки будут эмулировать Ctrl+* и Ctrl+/. Такие комбинации выбраны потому что одной рукой их выполнять неудобно а значит использоваться они будут вряд ли. Комбинацию можете подобрать и сами, воспользовавшись значением keysym для клавиши, определить которое можно при помощи всё той же xev. Запись кода в качестве параметра xvkbd должна выглядеть как \[keysym].
Вот так, слегка пошуршав двумя конфигами, мы добились желаемого.

09 октября 2007

Cut в Blogger

Реализовал сворачивание длинных постов в Блоггере на манер ЖЖ (см. предыдущий пост). Не удержался от пижонских эффектов.

01 октября 2007

intro

Этим полукреслом мастер Гамбс начинает новую партию мебели...
Этим постом начинается новый блог. Посвящён он будет в основном Linux и свободному ПО, однако в нём будет место и для тем из других областей IT.