<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Bappoy's blog</title>
	
	<link>http://bappoy.pp.ru</link>
	<description>Линуксоид на велосипеде с моторчиком</description>
	<lastBuildDate>Mon, 06 Feb 2012 08:28:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/bappoy" /><feedburner:info uri="bappoy" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Нижний Новгород в погодном апплете Gnome</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/Qcgz4r-UjyY/nnov_libgweather.html</link>
		<comments>http://bappoy.pp.ru/2012/02/06/nnov_libgweather.html#comments</comments>
		<pubDate>Mon, 06 Feb 2012 08:28:29 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[нижний новгород]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=1098</guid>
		<description>&lt;p&gt;Для того, чтобы наблюдать погоду в верхней панели, всю жизнь тщательно вбивал координаты нашего нижегородского аэропорта (ICAO: UWGG) в /usr/share/libgweather/locations.xml, т.к. в списке городов Нижнего Новгорода нет и не было, а при вводе &amp;#8220;nizh&amp;#8221; показывался только Nizhnevartovsk. На прошлой неделе решил окончательно разобраться с этим вопросом и обнаружил, что вместо Нижнего Новгорода нужно искать Стригино — поселок в черте города, поделившийся названием с аэропортом.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/Qcgz4r-UjyY" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2012/02/06/nnov_libgweather.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2012/02/06/nnov_libgweather.html</feedburner:origLink></item>
		<item>
		<title>Политическая позиция</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/eJOtAihxZSc/elections.html</link>
		<comments>http://bappoy.pp.ru/2011/12/02/elections.html#comments</comments>
		<pubDate>Fri, 02 Dec 2011 11:44:47 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[выборы]]></category>
		<category><![CDATA[политика]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=1092</guid>
		<description>&lt;p&gt;Пойду 4 декабря голосовать против партии &amp;#8220;Единая Россия&amp;#8221; по следующим причинам:&lt;/p&gt;
&lt;p&gt;1. Государственная дума — место для политических дискуссий;&lt;br /&gt;
2. Партия, которая:&lt;br /&gt;
 — имеет своей целью обеспечение беспрепятственного прохождения абсолютно любых законопроектов в государственной думе;&lt;br /&gt;
 — монополизировала и фактически подменила собой власть;&lt;br /&gt;
 — законодательно обеспечила большинство в последующих думах при отсутствии фактической поддержки среди населения;&lt;br /&gt;
 — без стеснения использует административный ресурс для обеспечения своей поддержки на выборах, явно нарушая законодательство, и ей сходит это с рук;&lt;br /&gt;
 — указывает в своих заслугах то, что она, являясь властью, и так должна делать;&lt;br /&gt;
 — грозит лишением федеральных денег целых регионов за то, что часть их населения не поддерживает;&lt;br /&gt;
— в начале своих федеральных и региональных списков указывает людей, которые заведомо не будут и не могут быть депутатами, а иногда даже и не являются членами этой партии —&lt;/p&gt;
&lt;p&gt;не должна иметь большинство в Думе.&lt;/p&gt;
&lt;p&gt;3. Коррупция, fail&amp;#8217;ы космической программы, провалы конкурсов на поставки военной техники союзникам, провал совместных тихоокеанских учений с Индией, слабость внешней политики, сомнительная олимпиада — всё это тоже заслуги Единой России.&lt;/p&gt;
&lt;p&gt;Сходите на выборы и явно выразите свое мнение, иначе неявно ваш голос отойдет этой партии.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/eJOtAihxZSc" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2011/12/02/elections.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2011/12/02/elections.html</feedburner:origLink></item>
		<item>
		<title>Пересборка ruby gem на примере hiredis в FreeBSD</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/9tgpROPvgxI/gem-hiredis-freebsd.html</link>
		<comments>http://bappoy.pp.ru/2011/11/06/gem-hiredis-freebsd.html#comments</comments>
		<pubDate>Sun, 06 Nov 2011 17:30:18 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[рабочие будни]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=1076</guid>
		<description>&lt;p&gt;Для тех админов, кому &lt;s&gt;лень&lt;/s&gt; некогда копаться во внутренностях ruby и гуглить невнятные ошибки, но надо срочно поставить ruby gem, отсутствующий в портах. В моем случае — hiredis (ruby обвязка для одноименной библиотеки доступа к БД redis). Установка методом
&lt;pre&gt;gem install hiredis&lt;/pre&gt;
&lt;p&gt; не работает, т.к. где-то внутри жестко зашито название утилиты make, а FreeBSD-версия  /usr/bin/make серьезно отличается по синтаксису от GNU Make, который все привыкли использовать, поэтому в STDERR сыпятся ошибки:&lt;/p&gt;
&lt;pre&gt;# gem install hiredis
Fetching: hiredis-0.4.1.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing hiredis:
	ERROR: Failed to build gem native extension.

        /usr/local/bin/ruby18 extconf.rb
"Makefile", line 11: Missing dependency operator
"Makefile", line 21: Need an operator
"Makefile", line 22: Missing dependency operator
"Makefile", line 33: Need an operator
"Makefile", line 43: Need an operator
"Makefile", line 44: Need an operator
"Makefile", line 82: Need an operator
"Makefile", line 86: Need an operator
"Makefile", line 88: warning: duplicate script for target "hiredis-example-ae" ignored
"Makefile", line 89: Need an operator
make: fatal errors encountered -- cannot continue
creating Makefile

make
cc -I. -I/usr/local/lib/ruby/1.8/amd64-freebsd8 -I/usr/local/lib/ruby/1.8/amd64-freebsd8 -I. -I/usr/include -fPIC -I/usr/include -O2 -pipe -fno-strict-aliasing -fPIC -I/usr/local/lib/ruby/gems/1.8/gems/hiredis-0.4.1/vendor/hiredis -c connection.c
cc -I. -I/usr/local/lib/ruby/1.8/amd64-freebsd8 -I/usr/local/lib/ruby/1.8/amd64-freebsd8 -I. -I/usr/include -fPIC -I/usr/include -O2 -pipe -fno-strict-aliasing  -fPIC  -I/usr/local/lib/ruby/gems/1.8/gems/hiredis-0.4.1/vendor/hiredis -c hiredis_ext.c
cc -I. -I/usr/local/lib/ruby/1.8/amd64-freebsd8 -I/usr/local/lib/ruby/1.8/amd64-freebsd8 -I. -I/usr/include    -fPIC -I/usr/include -O2 -pipe -fno-strict-aliasing -fPIC  -I/usr/local/lib/ruby/gems/1.8/gems/hiredis-0.4.1/vendor/hiredis -c reader.c
cc -shared -o hiredis_ext.so connection.o hiredis_ext.o reader.o -L. -L/usr/local/lib -Wl,-R/usr/local/lib -L. -L/usr/lib  -rpath=/usr/lib:/usr/local/lib -pthread -rdynamic /usr/local/lib/ruby/gems/1.8/gems/hiredis-0.4.1/vendor/hiredis/libhiredis.a -Wl,-soname,hiredis_ext.so   -Wl,-R -Wl,/usr/local/lib -L/usr/local/lib -lruby18  -lcrypt -lm -L/usr/lib  -rpath=/usr/lib:/usr/local/lib -pthread
cc: /usr/local/lib/ruby/gems/1.8/gems/hiredis-0.4.1/vendor/hiredis/libhiredis.a: No such file or directory
*** Error code 1

Stop in /usr/local/lib/ruby/gems/1.8/gems/hiredis-0.4.1/ext/hiredis_ext.

Gem files will remain installed in /usr/local/lib/ruby/gems/1.8/gems/hiredis-0.4.1 for inspection.
Results logged to /usr/local/lib/ruby/gems/1.8/gems/hiredis-0.4.1/ext/hiredis_ext/gem_make.out
&lt;/pre&gt;
&lt;p&gt;GNU-версия make в freebsd называется gmake. Чтобы исправить вызов make в gem&amp;#8217;е, пришлось его пересобрать. Вот полная версия установки пакета:&lt;/p&gt;
&lt;pre&gt;$ mkdir ~/hiredis &amp;#038;&amp;#038; cd ~/hiredis
$ gem fetch hiredis  # в текущем каталоге появляется файл hiredis-0.4.1.gem
Downloaded hiredis-0.4.1
$ gem unpack hiredis-0.4.1.gem
Unpacked gem: '/home/bvk/hiredis/hiredis-0.4.1'
$ gem spec  hiredis-0.4.1.gem &gt; hiredis.spec # извлекли спецификацию gem'а, по которой будем собирать пакет
$ cd hiredis-0.4.1
# тут в ext/hiredis_ext/extconf.rb нужно поменять "make static" на "gmake static",
# а в Rakefile "make clean" на "gmake clean"
# собираем пакет
$ gem build ../hiredis.spec
WARNING:  description and summary are identical
  Successfully built RubyGem
  Name: hiredis
  Version: 0.4.1
  File: hiredis-0.4.1.gem
# устанавливаем
$ sudo gem install hiredis-0.4.1.gem
Building native extensions.  This could take a while...
Successfully installed hiredis-0.4.1
1 gem installed
Installing ri documentation for hiredis-0.4.1...
Installing RDoc documentation for hiredis-0.4.1...&lt;/pre&gt;
&lt;p&gt;Теперь внимательно читаем porters handbook, делаем порт и далее действуем по правилам.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/9tgpROPvgxI" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2011/11/06/gem-hiredis-freebsd.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2011/11/06/gem-hiredis-freebsd.html</feedburner:origLink></item>
		<item>
		<title>Как я однажды тупил два дня на ровном месте</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/uwQUY4fvlxA/dst.html</link>
		<comments>http://bappoy.pp.ru/2011/10/18/dst.html#comments</comments>
		<pubDate>Tue, 18 Oct 2011 09:17:45 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[лытдыбр]]></category>
		<category><![CDATA[рабочие будни]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=515</guid>
		<description>&lt;p&gt;В преддверии первой годовщины последнего осеннего перевода часов в России вспомнился один факап трехлетней давности (начало 2008 года). Я тогда занимался починкой  статистики посещаемости на одном региональном сайтике, который я поддерживал по дружбе.&lt;/p&gt;
&lt;p&gt;У них было два сервера, один в интернете показывал контент посетителям, а второй располагался в офисе и содержал интерфейс администрирования сайта. Все хозяйство работало под FreeBSD 6.1 на очень стареньких машинах, на основном сервере  был Pentium 3 и 384 мегабайта памяти (однако много лет назад о такой конфигурации &lt;a href="http://www.lib.ru/WEBMASTER/wwwhard.txt#4"&gt;можно было лишь помечтать&lt;/a&gt;). Apache 2.2.2 вёл лог посещений в режиме &amp;#8220;combined&amp;#8221;, а по ночам всё накопленное за последние сутки обрабатывалось штатной программкой &lt;a href="http://httpd.apache.org/docs/2.2/programs/logresolve.html"&gt;logresolve&lt;/a&gt; (преобразовывает IP-адреса посетителей в имена хостов) и копировалось в отдельный файл resolved.log. Затем офисный сервер забирал получившийся файл по HTTP (в целях безопасности все &amp;#8220;альтернативные&amp;#8221; способы обмена файлами решили не использовать) и парсил его awstats&amp;#8217;ом. Такая вот нехитрая схемка. Но проработала она ровно два месяца до середины декабря 2006 года и перестала.&lt;br /&gt;
&lt;!--more--&gt;&lt;br /&gt;
Кроме нескольких программных ошибок обнаружилось еще пара стратегических провалов. Во-первых, офисный сервер иногда отключался из-за проблем с электричеством, и лог не забирался вовремя, а на следующий день просто дополнялся; после двух-трёх пропущенных дней файл с логами разросся до таких размеров, что даже в сжатом виде слишком долго передавался бы по http, и забирающий скрипт просто отваливался по таймауту. Во-вторых, установленный там logresolve натурально портил логи: читал из строки первые 1024 байта, обрабатывал IP-адрес и печатал их в STDOUT, завершив переводом строки; затем читались следующие 1024 байта и т.д. В результате строки, содержащие, например, длинные реферрерские URL, оказались разбитыми на несколько строк по 1024 байта каждая, что, возможно, не имело значения для awstats, но крайне затрудняло дополнительную обработку такого лога.&lt;/p&gt;
&lt;p&gt;В итоге с декабря 2006 года лог-файл увеличился в размерах до полутора гигабайт. Я решил, что лучше его разбить на месяцы и скормить эти месяцы парсеру поочерёдно, однако сначала нужно было разобраться с лишними разрывами строк. Быстренько набросал однострочник на sed, который удаляет лишние переводы строк, если в третьем поле не содержится даты.&lt;/p&gt;
&lt;p&gt;Однако несмотря на то, что на как на небольших, так и на довольно больших отрывках resolved.log данный скриптик отрабатывал относительно нормально, из реального лога читались только первые 170 мегабайт с копейками и скрипт надолго зависал. Решил, что, возможно, чего-то не учёл из-за малого опыта написания такого рода сценариев на sed, и переделал тот же самый алгоритм на perl и c  — безуспешно: после прочтения первых 170 мегабайт ничего не происходило.&lt;/p&gt;
&lt;pre&gt;my $b='';
while(&lt;&gt;){
        chomp;
        if(/\[[0-9]+\/[a-zA-Z]+\/[0-9:]+\ \+0300\]/){
                print "$b\n";
                $b=$_;
        } else {
                $b.=$_
        }
}
print "$b\n";
&lt;/pre&gt;
&lt;p&gt;Я несколько раз прогнал эти скрипты через valgrind с максимальными проверками утечек, избавился от некоторых ошибок, в конце концов перечитал кучу документации по freebsd на тему возможных ограничений на размер процесса в памяти (хотя больше восьми килобайт программа в памяти не занимала) и т.д. В общем, на два дня выпал из жизни, проводя это время в отладке&amp;#8230; &lt;/p&gt;
&lt;p&gt;В конце концов нашел причину моих мучений: в регулярном выражении, определявшем признак начала записи лога, была жестко прописана временная зона +0300, тогда как при переходе на летнее время она изменялась на +0400. Поэтому, когда цикл доходил до марта 2007 года, несколько сотен тысяч строк до следующего октября просто пропускались, а поскольку сервер был медленный, то на Ctrl+C и kill -TERM скрипты реагировали не сразу, и тем создавалось ощущение зависания.&lt;/p&gt;
&lt;p&gt;После того, как я исправил этот регэксп, всё пошло как по маслу: скормил awstats&amp;#8217;у старые логи, прикрутил logrotate, научил скрипты забирать статистику через scp; параллельно крону поставил &lt;a href="http://sourceforge.net/projects/anacron"&gt;anacron&lt;/a&gt;, благодаря чему забор и анализ логов стал производиться ежедневно вне зависимости от того, включен ли &amp;#8220;офисный&amp;#8221; сервер в 4 часа 15 минут утра. А потом и вовсе уговорил начальство поставить внешние счетчики. Теперь там стоит google analytics и все счастливы, а я немного прокачал скилл профайлинга.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/uwQUY4fvlxA" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2011/10/18/dst.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2011/10/18/dst.html</feedburner:origLink></item>
		<item>
		<title>Комфортная работа в Midnight Commander</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/zBfcKIrEGNc/mc.html</link>
		<comments>http://bappoy.pp.ru/2011/09/08/mc.html#comments</comments>
		<pubDate>Thu, 08 Sep 2011 13:28:49 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[mc]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=1026</guid>
		<description>&lt;p&gt;Многие мои коллеги принципиально игнорируют Midnight Commander, предпочитая работать в командной строке. Мотивируют это целым рядом причин, начиная с &amp;#8220;нортон коммандер устарел еще в 1995 году&amp;#8221; и заканчивая &amp;#8220;я юниксоид с 1970 года и без всяких mc прекрасно управляюсь в консоли&amp;#8221;. Конечно же, это дело вкуса, и можно (и нужно!) настроить консоль под себя так, чтобы она летала со скоростью мысли: на помощь приходят команда alias, сочетание Ctrl+R, описание команды shopt в builtins(1), пакет bash_completion или его аналоги, ряд мелких хаков, наподобие &lt;a href="http://bappoy.pp.ru/2008/11/17/quick-call-ssh.html"&gt;такого&lt;/a&gt;, или альтернатива в виде zsh, в конце концов.&lt;/p&gt;
&lt;p&gt;Однако визуалам типа меня удобнее постоянно иметь перед глазами списки файлов и папок, а не помнить, какой файл где находится и что здесь есть еще. Кроме того, пользуясь исключительно командами &lt;code&gt;cd&lt;/code&gt; и &lt;code&gt;ls --color&lt;/code&gt;, можно легко проглядеть что-нибудь ненужное, типа оставшихся от vim бэкапов в текущем каталоге (если бэкапы нужны, см &lt;code&gt;:help backupdir&lt;/code&gt;) или папок с именем из пробела. &lt;/p&gt;
&lt;p&gt;Конечно, сначала mc производит немного гнетущее впечатление, но если разобраться и привыкнуть, то может оказаться, что даже с конфигурацией из коробки он очень облегчает жизнь разработчика и системного администратора. Поделюсь собственными хитростями, используемыми каждый день. За кадром осталось еще множество интересных фич, типа кастомной раскраски файлов в панели, смены цветовой схемы на черно-зеленую, сниппетов в редакторе mcedit, настраиваемых VFS, но поскольку я ими не пользуюсь, то ничего про них не скажу. Примеры их настроек и использования можно посмотреть в /etc/mc и в /usr/share/mc.&lt;/p&gt;
&lt;p&gt;Сначала полезные мелочи, для многих очевидные.&lt;br /&gt;
&lt;!--more--&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Если до mc по каким-то причинам не доходят коды кнопок Fn, их можно заменить Esc-n. А Alt, иногда перехватываемый панелью меню, успешно заменяется кнопкой Esc
&lt;/li&gt;
&lt;li&gt;Режим просмотра файлов «Full file list» лучше, чем «Short file list». При желании можно добавить туда показ прав на объекты файловой системы, например:
&lt;pre&gt;half type name | size | mtime | mode:3&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Панели подсказок над и под командной строкой внизу и меню сверху можно отключить в Options — Layout, будет больше пространства для списка файлов. Заодно там можно включить отображение свободного места в текущем разделе — очень полезно для нетбуков с мелкими экранами&lt;/li&gt;
&lt;li&gt;При навигации по списку файлов сочетание &lt;b&gt;Ctrl+S&lt;/b&gt; перекидывает на файл, начинающийся с вводимых символов&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Alt+Y&lt;/b&gt; перекидывает в предыдущую папку. Иногда это бывает полезно при восстановлении после ошибки «The shell is already running the command», за все время существования mc ставшей его визиткой&lt;/li&gt;
&lt;li&gt;Встроенный редактор ужасен. В ~/.bashrc добавьте строчку &lt;code&gt;export EDITOR=vim&lt;/code&gt;, а в пункте меню Options — Configuration снимите галку «Use internal editor». Точно так же можно использовать переменную окружения PAGER=view для просмотра файлов (опция «Use internal view»)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Alt+I&lt;/b&gt; покажет текущую папку в противоположной панели, а &lt;b&gt;Alt+O&lt;/b&gt; — папку под курсором, а если под курсором файл, то родительскую.&lt;/li&gt;
&lt;li&gt;Начиная с ветки midnight commander 4.7.1, в меню сортировки появилась сортировка по версиям, она работает точно так же, как &lt;code&gt;ls -v&lt;/code&gt;, т.е. показывает список 1.2.1, 1.2.2, 1.2.10 именно в этом порядке, а не в алфавитном (1.2.1, 1.2.10, 1.2.2). Сам делал :).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ctrl+X c&lt;/b&gt; — просмотр и редактирование прав на файл&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Ctrl+X d&lt;/b&gt; — три варианта сравнения двух каталогов: быстрое (по спискам файлов), по размерам (то же самое, только с учетом размеров), полное (по содержимому файлов)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Alt+C&lt;/b&gt; — быстрый переход в нужную папку без изменения командной строки. По Esc-Tab показывает список подстановки (в командной строке mc Esc-Tab тоже иногда работает)&lt;/li&gt;
&lt;li&gt;По &lt;b&gt;Ctrl+\&lt;/b&gt; имеется многоуровневое меню быстрого доступа к папкам, в т.ч. и через FTP и SSH. При желании его можно отредактировать вручную в &lt;b&gt;~/.mc/hotlist&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;На данный момент самой полезной фичей для меня является пользовательское меню.  Про него я уже писал пару раз (&lt;a href="http://bappoy.pp.ru/2009/06/18/mc-tricks.html"&gt;1&lt;/a&gt;, &lt;a href="http://bappoy.pp.ru/2011/06/25/mc-unc-path.html"&gt;2&lt;/a&gt;), сейчас расскажу более подробно.&lt;/p&gt;
&lt;p&gt;Я поддерживаю несколько сайтов под mod_perl, и после изменений в коде startup.pl необходимо перезапускать процесс apache, свой для каждого сайта. Каждый сайт находится в /home/sites/sitename, а конфиг apache для этих сайтов — в /usr/local/apache/conf/httpd-sitename.conf.&lt;/p&gt;
&lt;p&gt;Когда мне надоело вручную писать /usr/local/apache/bin/apachectl-sitename restart после каждого изменения, в ~/.mc/menu добавились строчки:&lt;/p&gt;
&lt;pre&gt;s Restart apache for sitename
   sudo /usr/local/apache/bin/apachectl-sitename restart&lt;/pre&gt;
&lt;p&gt;Первая строка задаёт быструю клавишу и название пункта меню, а все за ней следующее — команду, в которой можно использовать ряд макро-подстановок:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;%f&lt;/b&gt; — имя файла под курсором, &lt;b&gt;%x&lt;/b&gt; — расширение, &lt;b&gt;%b&lt;/b&gt; — имя файла без расширения&lt;/li&gt;
&lt;li&gt;&lt;b&gt;%d&lt;/b&gt; — каталог в активной панели, &lt;b&gt;%D&lt;/b&gt; — каталог в неактивной панели
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;%t&lt;/b&gt; — выбранные файлы в активной панели, &lt;b&gt;%T&lt;/b&gt; — в неактивной&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;и т.д.&lt;/p&gt;
&lt;p&gt;Потом появилось еще пять подобных пунктов, для каждого сайта. В конце концов, мне надоело выбирать стрелками нужную команду или искать в длинном списке, какая буква соответствует соответствует нужному пункту. Внимательно перечитав справку, появляющуюся при нажатии F1 в меню F2, добавил еще по строчке к каждому определению пункта меню:&lt;/p&gt;
&lt;pre&gt;+= d /home/sites/sitename | f httpd-sitename.conf
s Restart apache for sitename
   sudo /usr/local/apache/bin/apachectl-sitename restart&lt;/pre&gt;
&lt;p&gt;Первый символ &amp;#8220;=&amp;#8221; означает начало условия, при котором пункт меню становится активным по умолчанию (при вызове меню курсор уже стоит на этом пункте, так что остаётся только нажать Enter); если перед ним стоит +, то пункт появляется в меню только при выполнении этого условия. Следующий символ — тип условия, например:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;f шаблон&lt;/b&gt; — имя файла соответствует шаблону (если в начале файла меню не указана опция shell_patterns=0, то под шаблоном имеется в виду шелл-шаблон, в противном случае — регулярное выражение)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;d шаблон&lt;/b&gt; — текущий каталог соответствует шаблону&lt;/li&gt;
&lt;li&gt;&lt;b&gt;t type&lt;/b&gt; — то, что под курсором, имеет тип:
&lt;ul&gt;
&lt;li&gt;n не является директорией&lt;/li&gt;
&lt;li&gt;r обычный файл&lt;/li&gt;
&lt;li&gt;d каталог&lt;/li&gt;
&lt;li&gt;l ссылка&lt;/li&gt;
&lt;li&gt;c последовательное устройство&lt;/li&gt;
&lt;li&gt;b блочное устройство&lt;/li&gt;
&lt;li&gt;f FIFO&lt;/li&gt;
&lt;li&gt;s сокет&lt;/li&gt;
&lt;li&gt;x исполняемый файл&lt;/li&gt;
&lt;li&gt;t отмеченный файл&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Различные типы можно комбинировать, например, &lt;code&gt;t rdl&lt;/code&gt; означает файл, каталог или ссылку&lt;/li&gt;
&lt;li&gt;остальные тесты можно подсмотреть в упомянутой справке&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Условия можно комбинировать и объединять, например:&lt;/p&gt;
&lt;pre&gt;
# если находимся в папке /home/sites/sitename и под курсором — файл .sql, показать этот пункт меню
+= d /home/sites/site_name &amp;amp; f *.sql
S import sql-file to database sitedb
   mysql sitedb &amp;lt; %f
&lt;/pre&gt;
&lt;p&gt;Таким образом, приведенный  ранее кусок означает &amp;#8220;если находимся в каталоге сайта или стоим на конфигурационном файле apache для него, показать команду перезапуска сервера и встать на нее курсором&amp;#8221;. &lt;/p&gt;
&lt;p&gt;Остальное — дело фантазии и техники. Достаточно подумать о том, какие рутинные действия выполняются достаточно часто, и просто автоматизировать их.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/zBfcKIrEGNc" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2011/09/08/mc.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2011/09/08/mc.html</feedburner:origLink></item>
		<item>
		<title>Теоретические основы HTTP LiveStreaming для iPod, iPhone и iPad</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/AXUm6txGWoM/http-livestreaming.html</link>
		<comments>http://bappoy.pp.ru/2011/07/21/http-livestreaming.html#comments</comments>
		<pubDate>Thu, 21 Jul 2011 11:59:45 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[Ссылки]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=1011</guid>
		<description>&lt;p&gt;&lt;em&gt;Пару недель назад в свободное от основной работы время безуспешно пытался подружить Adobe Flash Media Server с iPhone и iPad посредством &lt;a href="http://red5.org"&gt;Red5&lt;/a&gt;, установленного на FreeBSD. Не получилось (не встал &lt;a href="http://www.xuggle.com/xuggler/"&gt;xuggler&lt;/a&gt;, а без него не заработал &lt;a href="http://code.google.com/p/red5/source/browse/java/plugins/trunk/mpeg-ts/readme.txt"&gt;mpeg-ts&lt;/a&gt;), но ссылки остались.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Спецификации &lt;a href="http://www.apple.com/iphone/specs.html"&gt;iPhone&lt;/a&gt; и &lt;a href="http://www.apple.com/ipad/specs/"&gt;iPad&lt;/a&gt;, из которых следует, что поддерживаются профили H.264 Main Profile Level 3.1 и Simple с аудио AAC-LC до 160 Kbps, 48 кГц&lt;/p&gt;
&lt;p&gt;HTTP Live Streaming с точек зрения:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;#8230; &lt;a href="http://developer.apple.com/library/ios/#documentation/networkinginternet/conceptual/streamingmediaguide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008332-CH1-DontLinkElementID_31"&gt;Apple&lt;/a&gt; (теория), &lt;a href="http://developer.apple.com/library/ios/#technotes/tn2224/_index.html"&gt;best practices&lt;/a&gt;. Все можно реализовать стандартными (?) средствами Mac Os X.&lt;/li&gt;
&lt;li&gt;&amp;#8230; &lt;a href="http://www.longtailvideo.com/support/jw-player/jw-player-for-flash-v5/12534/video-delivery-http-pseudo-streaming"&gt;разработчиков JW Player&lt;/a&gt; (JW Player — HTML5/Flash плеер, умеющий воспроизводить как классические потоки RTP/RTSP, так и HTTP LiveStreaming)&lt;/li&gt;
&lt;li&gt;&amp;#8230; &lt;a href="http://habrahabr.ru/blogs/video/105715/"&gt;разработчиков erlyvideo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://docs.google.com/viewer?a=v&amp;#038;q=cache:FO0teTxer4kJ:andrewsblog.org/a_review_of_http_live_streaming.pdf+inurl:a_review_of_http_live_streaming.pdf&amp;#038;hl=en&amp;#038;pid=bl&amp;#038;srcid=ADGEESjKUcA0X2eaMWE4RU-vywxruYwDlHV2Wn-V-t9I-j5PPwuK2HEq3e89Sct1VC9nfhNzSDS15ISw58iOtenBJFYcgpgiUeqFSSxmDO8DTV4VyNmJouoYfRDAhmYJQOdUJqeahb-o&amp;#038;sig=AHIEtbTIcQ3x-TCHmtABTPeKiq0x1PFkpA"&gt;A Review of HTTP LiveStreaming&lt;/a&gt; — подробный разбор технологии в сравнении с RTP/RTSP и Adobe Flash Media. Изначально этот обзор был опубликован &lt;a href="http://andrewsblog.org/a_review_of_http_live_streaming.pdf"&gt;на сайте автора&lt;/a&gt;, но по каким-то причинам файл отсутствует и доступен только в кэше гугла.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/AXUm6txGWoM" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2011/07/21/http-livestreaming.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2011/07/21/http-livestreaming.html</feedburner:origLink></item>
		<item>
		<title>Конвертация Unix-style путей в UNC в Midnight Commander</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/wktKlqiZpoU/mc-unc-path.html</link>
		<comments>http://bappoy.pp.ru/2011/06/25/mc-unc-path.html#comments</comments>
		<pubDate>Sat, 25 Jun 2011 11:19:14 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[mc]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=970</guid>
		<description>&lt;p&gt;Тестовые релизы нашего продукта мы выкладываем в шару \\fs\testing, а готовые сборки и обновления для клиентов — в \\fs\release. У меня эти шары примонтированы соответственно как /mnt/testing и /mnt/release, и при составлении писем о выпуске релиза приходится вручную менять пути вида /mnt/testing/product/version_major/version_minor на \\fs\testing\product\&amp;#8230; &lt;/p&gt;
&lt;p&gt;Однажды мне это надоело и я добавил такую запись в ~/.mc/menu:&lt;/p&gt;
&lt;pre&gt;+ d /mnt/
p   Copy path in windows format to clipboard
    pwd|perl -ne 's|^/([^/])|//\1|g; s|/mnt/(products\|testing)|/fs/\1|g; s|/|\\|g;print'|xclip &amp;#038;&lt;/pre&gt;
&lt;p&gt;Теперь, если текущий каталог в Midnight Commander начинается на &amp;#8220;/mnt/&amp;#8221;, в меню F2 появляется пункт &amp;#8220;Convert path to windows format&amp;#8221;, при активации которого в буфер обмена помещается &amp;#8220;правильный&amp;#8221; UNC-путь к текущему каталогу.&lt;/p&gt;
&lt;p&gt;О том, почему в Windows используются неправильные слэши, можно узнать из &lt;a href="http://habrahabr.ru/blogs/testing/120652/"&gt;этой статьи&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Заметка из черновиков годовой давности, сейчас выкладываю другие релизы в другие шары :)&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/wktKlqiZpoU" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2011/06/25/mc-unc-path.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2011/06/25/mc-unc-path.html</feedburner:origLink></item>
		<item>
		<title>Пакетная система Debian: низкоуровневая работа с deb-пакетами</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/N1rvT8VnB34/low-level-deb.html</link>
		<comments>http://bappoy.pp.ru/2010/10/22/low-level-deb.html#comments</comments>
		<pubDate>Fri, 22 Oct 2010 12:30:30 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[deb]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[dpkg]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=945</guid>
		<description>&lt;h2&gt;Формат deb-пакета&lt;/h2&gt;
&lt;p&gt;Краеугольный камень пакетной системы Debian — это deb-пакет (см. &lt;a href="http://www.opennet.ru/man.shtml?topic=deb&amp;#038;category=5&amp;#038;russian=2"&gt;deb(5)&lt;/a&gt;), представляющий из себя архив формата &lt;a href="http://sourceware.org/binutils/docs-2.20/binutils/ar.html#ar"&gt;ar&lt;/a&gt;, внутри которого содержится три файла:&lt;br /&gt;
1. debian-binary — текстовый файл, содержащий версию формата deb-пакета, в данный момент это 2.0. Программы, работающие с deb-пакетами, должны читать только первую строку этого файла и не падать, если минорная версия вдруг поменяется (например, станет 2.1).&lt;br /&gt;
2. control.tar.gz — служебная информация о пакете, скрипты, вспомогательные файлы (см deb-control(5)). Должен содержать только файлы, единственная папка, которая может присутствовать&amp;nbsp;— &amp;#8220;.&amp;#8221; (текущая директория). В этот архив обязательно должен входить файл control, его минимальное содержимое рассмотрим чуть ниже.&lt;br /&gt;
3. data.tar — собственно файлы, устанавливаемые в систему.  Чаще всего этот файл сжат каким-нибудь архиватором (поддерживаются расширения .gz, .xz, .bz2, .lzma), чаще всего в архивах встречается data.tar.gz.&lt;br /&gt;
&lt;!--more--&gt;&lt;br /&gt;
Указанный порядок следования файлов в архиве обязателен. Если в этом архиве требуется разместить еще какие-нибудь файлы (не представляю, зачем это может кому-нибудь понадобиться), они должны находиться перед data.tar.gz, т.е. последний файл в архиве всегда data.tar. Но если сообщество когда-нибудь решит добавить в формат deb еще файлы, они будут помещены после data.tar.&lt;/p&gt;
&lt;p&gt;Файл control в архиве control.tar.gz описывает назначение, версию и зависимости пакета, его формат более-менее подробно описан в &lt;a href="http://www.opennet.ru/man.shtml?topic=deb-control&amp;#038;russian=2"&gt;deb-control(5)&lt;/a&gt;. Пересказывать всю справку сейчас не буду, опишу лишь минимальное содержимое, необходимое для взаимодействия с инфраструктурой dpkg:&lt;/p&gt;
&lt;pre&gt;Package: имя пакета
Version: строка версии (при выборе политики назначения версий следует придерживаться &lt;a href="http://manpages.debian.net/cgi-bin/man.cgi?query=deb-version&amp;#038;sektion=&amp;#038;apropos=0&amp;#038;manpath=Debian%205.0%20lenny"&gt;deb-version(5)&lt;/a&gt;)
Maintainer: John Doe &amp;lt;johndoe@foo.com&amp;gt; (человек, поддерживающий пакет, а не автор программы)
Description: короткое описание пакета
 Длинное описание,  на несколько строк. Каждая строка, входящая в
 длинное описание,  должна начинаться с пробела&lt;/pre&gt;
&lt;h2&gt;Работа с пакетами средствами ar&lt;/h2&gt;
&lt;p&gt;Теоретически данной информации должно быть достаточно, чтобы собрать простейший пакет &amp;#8220;на коленке&amp;#8221; и установить его в систему. Пусть наш пакет (назовем его test) просто добавляет в систему  файл /usr/share/example-content/test со строчкой &amp;#8220;test&amp;#8221;. Сделаем архив data.tar.gz со структурой папок и единственным файлом, а также файлик debian-binary:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;mkdir -p usr/share/example-content/&lt;/strong&gt;
$&lt;strong&gt; echo test &amp;gt; usr/share/example-content/test&lt;/strong&gt;
$&lt;strong&gt; tar czf data.tar.gz usr&lt;/strong&gt;
$ &lt;strong&gt;echo 2.0 &amp;gt; debian-binary&lt;/strong&gt;&lt;/pre&gt;
&lt;p&gt;Создадим файл &lt;code&gt;control&lt;/code&gt; со следующим содержанием:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;cat control&lt;/strong&gt;
Package: test
Version: 1.0
Maintainer: Dummy Maint &amp;lt;dummy@example.org&amp;gt;
Description: test package
 Test package created on my own knees.
$ tar czf control.tar.gz control&lt;/pre&gt;
&lt;p&gt;Теперь соберем все воедино:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;ar -qS test-1.0.deb debian-binary control.tar.gz data.tar.gz&lt;/strong&gt;&lt;/pre&gt;
&lt;p&gt;В текущем каталоге должен появиться файл &lt;code&gt;test-1.0.deb&lt;/code&gt;. Его &amp;#8220;физическое&amp;#8221; содержимое можно просмотреть  с помощью следующей команды:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;ar t test-1.0.deb&lt;/strong&gt;
debian-binary
control.tar.gz
data.tar.gz&lt;/pre&gt;
&lt;p&gt;Посмотреть файл debian-binary:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;ar p test-1.0.deb debian-binary&lt;/strong&gt;
2.0&lt;/pre&gt;
&lt;p&gt;Посмотреть список файлов в пакете:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;ar p test-1.0.deb data.tar.gz|tar -tzf -&lt;/strong&gt;
usr/
usr/share/
usr/share/example-content/
usr/share/example-content/test&lt;/pre&gt;
&lt;p&gt;Посмотреть содержимое файла control:&lt;/p&gt;
&lt;pre&gt;$&lt;strong&gt; ar p test-1.0.deb control.tar.gz |tar -O -xzf - control&lt;/strong&gt;
Package: test
Version: 1.0
Maintainer: Dummy Maint &amp;lt;dummy@example.org&amp;gt;
Description: test package
 Test package created on my own knees.&lt;/pre&gt;
&lt;p&gt;Можно установить этот пакет и убедиться, что файл &lt;code&gt;/usr/share/example-content/test&lt;/code&gt; успешно создан, но лучше этого не делать, поскольку из-за недостатка информации в control в пакетной системе может появиться мусор:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;sudo dpkg -i test-1.0.deb&lt;/strong&gt;
Selecting previously deselected package test.
(Reading database ... 97631 files and directories currently installed.)
Unpacking test (from test-1.0.deb) ...
Setting up test (1.0) ...&lt;/pre&gt;
&lt;h2&gt;Работа с пакетами средствами dpkg-deb&lt;/h2&gt;
&lt;p&gt;Все вышеописанное позволяет управляться с deb-пакетами на самом низком уровне, не имея под рукой ничего, кроме стандартных средств Unix (доподлинно известно, что программа ar входила в состав первых Unix 1970х годов). Однако, как несложно догадаться, есть и более высокоуровневые способы создания пакетов и изучения их содержимого. В частности, если уж так необходимо поковыряться с пакетом на низком уровне, все вышеописанные действия настоятельно рекомендуется выполнять с помощью утилиты dpkg-deb(1).&lt;/p&gt;
&lt;h3&gt;Создание пакета средствами dpkg-deb&lt;/h3&gt;
&lt;p&gt;Минимальный формат вызова команды dpkg-deb для построения пакета следующий:&lt;/p&gt;
&lt;pre&gt;&lt;strong&gt;dpkg-deb -b исходная_папка&lt;/strong&gt;&lt;/pre&gt;
&lt;p&gt;Все, что находится в исходной папке, кроме директории DEBIAN, помещается в data.tar.gz. Содержимое DEBIAN будет использовано для создания control.tar.gz, в частности, будет прочитан и проанализирован файл control и в случае каких-либо ошибок (отсутствует одно из необходимых полей или эти поля имеют неправильные значения) пакет просто не будет создан. Процесс создания нашего тестового пакета с нуля теперь выглядит так (в последней команде предполагается, что в текущей папке остался файл control от сборки пакета средствами ar):&lt;/p&gt;
&lt;p&gt;Подготовка структуры:&lt;/p&gt;
&lt;pre&gt;&lt;strong&gt;$ mkdir -p test-1.1/usr/share/example-content/ test-1.1/DEBIAN&lt;/strong&gt;
$ &lt;strong&gt;echo test 1.1 &amp;gt; test-1.1/usr/share/example-content/test&lt;/strong&gt;
$ &lt;strong&gt;sed 's/Version: 1.0/Version: 1.1/g' control &amp;gt; test-1.1/DEBIAN/control&lt;/strong&gt;&lt;/pre&gt;
&lt;p&gt;Попытаемся собрать пакет:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;dpkg-deb -b test-1.1&lt;/strong&gt;
warning, in file 'test-1.1/DEBIAN/control' near line 5 package 'test':
 missing architecture
dpkg-deb: building package `test' in `test-1.1.deb'.
dpkg-deb: warning: ignoring 1 warnings about the control file(s)&lt;/pre&gt;
&lt;p&gt;Несмотря на отсутствие важного, но не необходимого поля Architecture, был создан пакет test-1.1.deb. Добавим поле и пересоздадим пакет:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;sed -i "1a \
Architecture: all" test-1.1/DEBIAN/control&lt;/strong&gt;
$ &lt;strong&gt;dpkg-deb -b test-1.1&lt;/strong&gt;
dpkg-deb: building package `test' in `test-1.1.deb'&lt;/pre&gt;
&lt;p&gt;Еще одна немаловажная деталь. Как правило, в названии файла пакета указывается его архитектура, а команда &lt;code&gt;dpkg-deb -b&lt;/code&gt; назвала файл по имени папки, из которой он был создан. Если бы папка называлась ololo, то мы получили бы ololo.deb. Чтобы файл пакета автоматически именовался в формате имя-версия-архитектура, при вызове dpkg -b необходимо указывать папку, куда будет положен итоговый архив, например, текущую. Тогда все компоненты имени файла будут извлечены из control:&lt;/p&gt;
&lt;pre&gt;$ cp -R test-1.1 ololo
$ dpkg -b ololo
dpkg-deb: building package `test' in `ololo.deb'.
$ dpkg -b ololo .
dpkg-deb: building package `test' in `./test_1.1_all.deb'.&lt;/pre&gt;
&lt;p&gt;Теперь всё относительно нормально, продолжаем изучение возможностей dpkg-deb на примере нового пакета.&lt;/p&gt;
&lt;h3&gt;Получение информации о пакете&lt;/h3&gt;
&lt;p&gt;Узнать версию формата deb, размер пакета и содержимое файла control:&lt;/p&gt;
&lt;pre&gt;$ dpkg -I test_1.1_all.deb
 new debian package, version 2.0.
 size 644 bytes: control archive= 259 bytes.
     160 bytes,     6 lines      control
 Package: test
 Architecture: all
 Version: 1.1
 Maintainer: Dummy Maint &amp;lt;dummy@example.org&amp;gt;
 Description: test package
  Test package created on my own knees.&lt;/pre&gt;
&lt;p&gt;Список файлов, устанавливаемых в систему (кроме служебных):&lt;/p&gt;
&lt;pre&gt;$ dpkg -c test_1.1_all.deb
drwxr-xr-x bvk/bvk           0 2010-10-22 13:21 ./
drwxr-xr-x bvk/bvk           0 2010-10-22 13:21 ./usr/
drwxr-xr-x bvk/bvk           0 2010-10-22 13:21 ./usr/share/
drwxr-xr-x bvk/bvk           0 2010-10-22 13:21 ./usr/share/example-content/
-rw-r--r-- bvk/bvk           9 2010-10-22 13:21 ./usr/share/example-content/test&lt;/pre&gt;
&lt;p&gt;Обратите внимание на владельца устанавливаемых файлов и каталогов: это не root, а некий пользователь. Чтобы исправить эту проблему, можно собирать пакеты из-под root&amp;#8217;а, либо воспользоваться специальной утилитой &lt;code&gt;fakeroot&lt;/code&gt; из одноименного пакета. Она перехватывает системные вызовы &lt;code&gt;chmod(2)&lt;/code&gt; и&lt;code&gt; stat(2)&lt;/code&gt; для файлов, и возвращает значения, как если бы файл принадлежал пользователю root. Небольшой пример:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;id&lt;/strong&gt;
uid=1000(bvk) gid=1000(bvk) ...
$&lt;strong&gt; touch trololo&lt;/strong&gt;
$ &lt;strong&gt;ls -l trololo&lt;/strong&gt;
-rw-r--r-- 1 bvk bvk 0 2010-10-22 13:23 trololo
$ &lt;strong&gt;fakeroot ls -l trololo &lt;/strong&gt;
-rw-r--r-- 1 root root 0 2010-10-22 13:23 trololo&lt;/pre&gt;
&lt;p&gt;Думаю, принцип понятен. Пересоберем пакет еще более правильно:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;fakeroot dpkg -b test-1.1 .&lt;/strong&gt;
dpkg-deb: building package `test' in `test_1.1_all.deb'.
$ &lt;strong&gt;dpkg -c test_1.1_all.deb&lt;/strong&gt;
drwxr-xr-x root/root         0 2010-10-22 13:25 ./
drwxr-xr-x root/root         0 2010-10-22 13:25 ./usr/
drwxr-xr-x root/root         0 2010-10-22 13:25 ./usr/share/
drwxr-xr-x root/root         0 2010-10-22 13:25 ./usr/share/example-content/
-rw-r--r-- root/root         9 2010-10-22 13:25 ./usr/share/example-content/test&lt;/pre&gt;
&lt;p&gt;Теперь наконец ок.&lt;/p&gt;
&lt;p&gt;Можно получаить информацию о пакете в заданном формате:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;dpkg-deb -W --showformat='${Package}-${Version}-${Architecture} (${Maintainer})\n' &lt;/strong&gt;test_1.1_all.deb
test-1.1-all (Dummy Maint &amp;lt;dummy@example.org&amp;gt;)&lt;/pre&gt;
&lt;p&gt;Список полей, которые можно указать в &amp;#8211;showformat, можно узнать из вывода команды &lt;code&gt;dpkg-deb -I&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Подать на STDOUT архив data.tar.gz из пакета (уже &amp;#8220;разжатый&amp;#8221;), может быть полезно для извлечения только некоторых файлов:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;dpkg-deb --fsys-tarfile test-1.0.deb |tar -Ox usr/share/example-content/test&lt;/strong&gt;
test&lt;/pre&gt;
&lt;h2&gt;Перепаковка пакета&lt;/h2&gt;
&lt;p&gt;Пожалуй, теперь наступил момент применить свежеполученные знания на практике :) Часто возникает следующая проблема: из некоего источника поступил пакет с некорректными зависимостями, например, требуется устаревший пакет, отсутствующий в системе и всех репозиториях, но доподлинно известно, что другой, уже установленный пакет предоставляет нужную функциональность. В скачанном пакете требуется изменить файл control, убрав или исправив зависимость. Правильно было бы скачать и распаковать исходник пакета (apt-get source), произвести необходимые изменения в скриптах сборки, установить все необходимые для пересборки библиотеки и окружение и т.д. и т.п., но для частного использования (т.е. без распространения по репозиториям) достаточно просто распаковать пакет, изменить необходимые файлы и запаковать обратно. Проиллюстрирую последовательность действий на примере невинного пакета hello:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;aptitude download hello&lt;/strong&gt;
Get:1 http://yum.fireground.ru/ubuntu/mirror/ maverick/main hello i386 2.5-1 [34.4kB]
Fetched 34.4kB in 0s (824kB/s)
# да-да, я сижу под убунтой и описываю debian
# распаковать содержимое пакета в папку hello (если не существует, будет создана):
$ &lt;strong&gt;dpkg-deb -x hello_2.5-1_i386.deb hello&lt;/strong&gt;
# распаковать содержимое control.tar.gz в hello/DEBIAN
$ &lt;strong&gt;dpkg-deb -e hello_2.5-1_i386.deb hello/DEBIAN&lt;/strong&gt;
# что-нибудь поменять в control, например, версию пакета:
$ &lt;strong&gt;sed -i 's/Version: .*$/Version: 2.5-1test/' hello/DEBIAN/control &lt;/strong&gt;
# собрать новый пакет:
$ &lt;strong&gt;fakeroot dpkg -b hello/ .&lt;/strong&gt;
dpkg-deb: warning: 'hello//DEBIAN/control' contains user-defined field 'Original-Maintainer'
dpkg-deb: building package `hello' in `./hello_2.5-1test_i386.deb'.
dpkg-deb: warning: ignoring 1 warnings about the control file(s)&lt;/pre&gt;
&lt;p&gt;Пакет собран. Убедиться, в том, что  в нем нет ошибок из-за немного нетрадиционного способа сборки, можно с помощью программы lintian:&lt;/p&gt;
&lt;pre&gt;$ &lt;strong&gt;sudo aptitude install lintian&lt;/strong&gt;
...
$ &lt;strong&gt;lintian hello_2.5-1test_i386.deb&lt;/strong&gt;
$ &lt;strong&gt;echo $?&lt;/strong&gt;
0&lt;/pre&gt;
&lt;p&gt;Всё в порядке!&lt;/p&gt;
&lt;p&gt;Об установке пакетов в систему, механизме зависимостей, структуре репозиториев и еще более правильных способах сборки пакетов читайте в следующих статьях :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/N1rvT8VnB34" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/10/22/low-level-deb.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2010/10/22/low-level-deb.html</feedburner:origLink></item>
		<item>
		<title>Проблема “SSL input filter read failed” и её решение</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/Zo5NdMoZaCY/ssl-input-filter-read-failed.html</link>
		<comments>http://bappoy.pp.ru/2010/09/06/ssl-input-filter-read-failed.html#comments</comments>
		<pubDate>Mon, 06 Sep 2010 13:06:03 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[mod_ssl]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=976</guid>
		<description>&lt;p&gt;Потратил половину своих выходных на выяснение причин неработоспособности прикрученного мной к одному апачу 2.2.16 модуля mod_ssl. Скрипт, вроде бы нормально работающий на 80 порту, напрочь отказывался работать через https, при этом выдавалась пустая страница, а в логах при перезапуске апача появлялась строчка, свидетельствующая лишь о том, что используется самоподписанный сертификат:&lt;/p&gt;
&lt;pre&gt;[warn] RSA server certificate is a CA certificate (BasicConstraints: CA == TRUE !?)&lt;/pre&gt;
&lt;p&gt;Включив подробные логи (LogLevel debug), получил  для каждого запроса на пару порядков больше информации, из которой наиболее полезным оказалось вот это:&lt;/p&gt;
&lt;pre&gt;[Sat Sep 04 20:43:54 2010] [debug] ssl_engine_io.c(1893): OpenSSL: I/O error,
5 bytes expected to read on BIO#8074a22e0 [mem: 8074e5000]
[Sat Sep 04 20:43:54 2010] [info] [client XX.XX.XX.XX] (70007)The timeout
specified has expired: SSL input filter read failed.&lt;/pre&gt;
&lt;p&gt;Безрезультатно промаявшись с этим еще пару часов, отправился спать с мыслью поставить потом nginx в качестве SSL-прокси.&lt;/p&gt;
&lt;p&gt;В понедельник программисты посоветовали обратить внимание на .htaccess, в котором, в частности, активно эксплуатировался mod_rewrite и устанавливались настройки php. Временное удаление .htaccess вызвало ошибку 403 по нужному адресу (это был отличный результат, поскольку ранее никаких ошибок не выдавалось вообще). А отключение &lt;code&gt;php_value error_reporting 0&lt;/code&gt;, приведшее к заполнению экрана ошибками PHP, окончательно развеяло все сомнения: проблема была вовсе не в mod_ssl, а в пользовательском скрипте; mod_ssl ничего не получал и возвращал ошибку.&lt;/p&gt;
&lt;p&gt;Мораль на будущее: надо быть проще и искать корни очевидных ошибок на поверхности, а nginx все равно не помешает.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note for english-speaking visitors with the same error from google: try to check your php scripts or other backends, they can fail and not return any data to mod_ssl&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/Zo5NdMoZaCY" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/09/06/ssl-input-filter-read-failed.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2010/09/06/ssl-input-filter-read-failed.html</feedburner:origLink></item>
		<item>
		<title>Следующий месяц в GNU date</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/XzYjppVc1XA/date-next-month.html</link>
		<comments>http://bappoy.pp.ru/2010/08/31/date-next-month.html#comments</comments>
		<pubDate>Tue, 31 Aug 2010 11:37:44 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[pitfalls]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=971</guid>
		<description>&lt;p&gt;Если 31 августа спросить у GNU date, какой будет следующий месяц, результат будет немного странным:&lt;/p&gt;
&lt;pre&gt;$ date
Tue Aug 31 11:32:35 UTC 2010
$ date +"%Y-%m" --date "next month"
2010-10
$ date +"%Y-%m" --date "next month"
2010-10&lt;/pre&gt;
&lt;p&gt;Документация GNU date (см &lt;code&gt;info date Relative items in date strings&lt;/code&gt;) специально обращает внимание на эту проблему и рекомендует вычислять следующий месяц не для сегодняшнего числа, а для 15 числа текущего месяца:&lt;/p&gt;
&lt;pre&gt;$ date +"%Y-%m" --date "$(date +%Y-%m-15) next month"
2010-09&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/XzYjppVc1XA" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/08/31/date-next-month.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2010/08/31/date-next-month.html</feedburner:origLink></item>
		<item>
		<title>Извлечение данных из виртуальных дисков VirtualBox</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/nvuJ1GZhWeY/mount-fs-from-vdi.html</link>
		<comments>http://bappoy.pp.ru/2010/07/21/mount-fs-from-vdi.html#comments</comments>
		<pubDate>Wed, 21 Jul 2010 15:51:42 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[fs]]></category>
		<category><![CDATA[mount]]></category>
		<category><![CDATA[virtualbox]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=940</guid>
		<description>&lt;p&gt;Однажды глубокой ночью мне позарез понадобилось вытащить из остановленной виртуальной машины Virtualbox, находящейся на моем рабочем компьютере, один файлик. Удаленно запустить виртуальную машину и тем более подключиться к ней не получилось, поэтому я решил попробовать вытащить нужный раздел из vdi и смонтировать его. Ситуация немного осложнялась тем, что виртуальный жесткий диск хоть и содержал всего один корневой раздел, но был динамически расширяющимся, а это значит, что блоки файловой системы располагались в хронологическом порядке, а не в том, который ожидает драйвер файловой системы.&lt;/p&gt;
&lt;p&gt;К счастью, можно легко преобразовать vdi из динамического формата в статический с помощью многоцелевой утилиты vboxmanage, входящей в состав пакета virtualbox:&lt;/p&gt;
&lt;pre&gt;vboxmanage clonehd --variant static debian.vdi temp.vdi&lt;/pre&gt;
&lt;p&gt;Теперь у нас есть файл temp.vdi, внутри которого где-то присутствует образ искомой файловой системы; для ее корректного извлечения нужно вычислить смещение образа относительно начала файла. В половине найденных по запросу &amp;#8220;mount vdi linux&amp;#8221; статей рекомендуется использовать для этих целей утилиту vditool, предназначенную на самом деле для внутреннего тестирования функциональности виртуальных дисков в VirtualBox. Раньше бинарник vditool можно было отдельно скачать с сайта virtualbox.org, но теперь его там по понятным причинам нет (желающие могут скомпилировать его самостоятельно: &lt;a href="http://www.virtualbox.org/browser/trunk/src/VBox/Devices/Storage/testcase/vditool.cpp"&gt;vditool.cpp&lt;/a&gt;) &lt;/p&gt;
&lt;p&gt;Мы, как всегда, пойдем другим путем и воспользуемся подручными средствами. Первые 512 байт нашего vdi-файла — его заголовок, в котором можно разобраться, воспользовавшись, например, &lt;a href="http://forums.virtualbox.org/viewtopic.php?p=29267&amp;#038;sid=f13e432626fbf4b62807f7eb6fde8345#p292678"&gt;этим мануалом&lt;/a&gt; или непосредственно описанием &lt;a href="http://www.virtualbox.org/browser/trunk/src/VBox/Devices/Storage/VDICore.h#L135"&gt;структуры заголовка vdi&lt;/a&gt; в исходниках VirtualBox. Из этих источников следует, что образ размечен следующим образом:&lt;br /&gt;
512 байт: заголовок&lt;br /&gt;
4 * N + X: карта мегабайтных блоков, здесь N ­— количество мегабайт в виртуальном жестком диске, а X — выравнивание получившегося числа до ближайшей верхней 512-байтной границы&lt;br /&gt;
512 + 4*N + выравнивание: смещение данных&lt;/p&gt;
&lt;p&gt;Зная точный размер виртуального диска, можно легко вычислить смещение вручную:&lt;/p&gt;
&lt;pre&gt;$ vboxmanage showhdinfo f8e0de05-1419-405d-92d9-8358dc1e6bec
VirtualBox Command Line Management Interface Version 3.0.8_OSE
(C) 2005-2009 Sun Microsystems, Inc.
All rights reserved.

UUID:                 f8e0de05-1419-405d-92d9-8358dc1e6bec
Accessible:           yes
Description:
Logical size:         4095 MBytes
Current size on disk: 2637 MBytes
Type:                 normal (base)
Storage format:       VDI
In use by VMs:        debian (UUID: f1f8221a-6542-4dfe-9062-5397f429da4b)
Location:             /home/bvk/.VirtualBox/HardDisks/debian.vdi
&lt;/pre&gt;
&lt;p&gt;(UUID нужного диска можно узнать из вывода команды vboxmanage list hhds). Здесь выравненное до 512 значение размера карты блоков равно 16384, а смещение данных — 16896.&lt;br /&gt;
А можно и вытащить смещение непосредственно из заголовка vdi. Например, вот начало моего четырёхгигового виртуального диска:&lt;/p&gt;
&lt;pre&gt;$ head -c 512 temp.vdi |hexdump  -C
00000000  3c 3c 3c 20 53 75 6e 20  56 69 72 74 75 61 6c 42  |&amp;lt; &amp;lt;&amp;lt; Sun VirtualB|
00000010  6f 78 20 44 69 73 6b 20  49 6d 61 67 65 20 3e 3e  |ox Disk Image &amp;gt;&amp;gt;|
00000020  3e 0a 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |&amp;gt;...............|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000040  7f 10 da be 01 00 01 00  80 01 00 00 02 00 00 00  |................|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000150  00 00 00 00 00 02 00 00  &lt;b&gt;00 42 00 00&lt;/b&gt; 00 00 00 00  |.........B......|
00000160  00 00 00 00 00 00 00 00  00 02 00 00 00 00 00 00  |................|
00000170  00 00 f0 ff 00 00 00 00  00 00 10 00 00 00 00 00  |................|
00000180  ff 0f 00 00 ff 0f 00 00  db fa c4 c9 fd 13 ea 49  |...............I|
00000190  9e ae 4e 47 43 3f a0 3c  46 37 6c be e6 fd 02 40  |..NGC?.&amp;lt;f7l ....@|
000001a0  a7 63 44 3f 6e 3f 26 d8  00 00 00 00 00 00 00 00  |.cD?n?&amp;amp;.........|
000001b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001c0  00 00 00 00 00 00 00 00  0a 02 00 00 ff 00 00 00  |................|
000001d0  3f 00 00 00 00 02 00 00  00 00 00 00 00 00 00 00  |?...............|
000001e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200&lt;/pre&gt;
&lt;p&gt;Жирным шрифтом выделены необходимые четыре байта offsetData по смещению 0&amp;#215;0158. Можно искать их визуально, помня о little-endian-порядке байт (в этом случае искомое значение равно 0&amp;#215;00004200), а можно воспользоваться простенькой командой:&lt;/p&gt;
&lt;pre&gt;$ head -c 348 temp.vdi |tail -c 4|perl -ne 'print unpack("L",$_),"\n"'
16896&lt;/pre&gt;
&lt;p&gt;В любом случае, лишний раз перепроверить себя никогда не помешает.&lt;/p&gt;
&lt;p&gt;Посмотрим, что находится по этому смещению. Сразу можно предположить, что там располагается начало образа жесткого диска, из этого следует, что первые 512 байт содержат mbr. Проверим:&lt;/p&gt;
&lt;pre&gt;$ dd if=temp.vdi bs=512 count=1 skip=$((16896/512))|file -
1+0 records in
1+0 records out
512 bytes (512 B) copied, 3.9397e-05 s, 13.0 MB/s
/dev/stdin: x86 boot sector; partition 1: ID=0x83, active, starthead 1,
startsector 63, 7903917 sectors; partition 2: ID=0x5, starthead 0, startsector
7903980, 481950 sectors, code offset 0x4c&lt;/pre&gt;
&lt;p&gt;Жесткий диск содержит 2 раздела: основной размером 3859 мегабайт, начинающийся с 63 сектора (1 сектор — 512 байт), и расширенный 235 мегабайт, отведенный установщиком Debian под swap (вот это сюрприз на виртуалке). Для очистки совести проверяем заголовок первого раздела:&lt;/p&gt;
&lt;pre&gt;$ dd if=temp.vdi bs=512 count=3 skip=$((16896/512+63))|file -
3+0 records in
3+0 records out
1536 bytes (1.5 kB) copied, 4.7716e-05 s, 32.2 MB/s
/dev/stdin: Linux rev 1.0 ext3 filesystem data,
UUID=5ac94027-bf6e-43bc-9c3e-8a7830fe4ff8 (needs journal recovery) (large files)&lt;/pre&gt;
&lt;p&gt;То, что надо! Осталось смонтировать. Несколько лет назад пришлось бы дополнительно извлекать все 7903917 секторов в отдельный файл и монтировать его, но сейчас можно просто указать смещение от начала файла как опцию mount (оставшиеся расширенный раздел и swap внутри него будут проигнорированы):&lt;/p&gt;
&lt;pre&gt;$ sudo mount -o loop,offset=$((16896+63*512)) temp.vdi mnt
$ ls mnt/
bin   cdrom  etc   initrd.img      lib         media  opt   root  selinux  sys  usr  vmlinuz
boot  dev    home  initrd.img.old  lost+found  mnt    proc  sbin  srv      tmp  var  vmlinuz.old&lt;/pre&gt;
&lt;p&gt;Задача решена, все свободны.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/nvuJ1GZhWeY" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/07/21/mount-fs-from-vdi.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2010/07/21/mount-fs-from-vdi.html</feedburner:origLink></item>
		<item>
		<title>Линус Торвальдс о Eee PC</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/SHyAEFgGcsc/linus-about-eeepc.html</link>
		<comments>http://bappoy.pp.ru/2010/01/29/linus-about-eeepc.html#comments</comments>
		<pubDate>Fri, 29 Jan 2010 11:49:40 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[asus eee pc]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[linus]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=915</guid>
		<description>&lt;p&gt;В предыдущем посте — &lt;a href="http://bappoy.pp.ru/2010/01/29/linus-about-embroidery.html"&gt;небольшая история&lt;/a&gt; о том, как в Linux была улучшена поддержка устройств экстра-маленького размера благодаря покупки Линусом Торвальдсом вышивальной машинки :) В &lt;a href="http://article.gmane.org/gmane.linux.utilities.util-linux-ng/2888"&gt;письме Линуса&lt;/a&gt; в рассылку util-linux-ng@kernel.org было упомянуто, что для управления этой машинкой он использует Eee PC с Fedora 12 на борту. Как &lt;a href="http://bappoy.pp.ru/2008/05/06/eee-first-impressions.html"&gt;пользователь Eee PC 701g&lt;/a&gt; с почти двухлетним стажем, я заинтересовался и написал Линусу письмо с несколькими вопросами о его опыте использования этих компьютеров. Получилось мини-интервью, которое и предлагается вашему вниманию.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: Какие модели Eee PC Вы используете?&lt;/strong&gt;&lt;br /&gt;
A: У меня их две штуки: 701 и 901.&lt;/p&gt;
&lt;p&gt;Q: Это основной компьютер или один из дополнительных?&lt;br /&gt;
A: Нет, конечно же, это не основной компьютер. Atom тормозной как грех. Я считаю, что процессоры с прямым выполнением команд (in-order execution) — преступление против человечности, и я уверен в том, что если Intel не предпримет значительных шагов (т.е. сделает Atom &lt;a href="http://en.wikipedia.org/wiki/Out-of-order_execution"&gt;out-of-order&lt;/a&gt;), ARM Cortex A9 захватит рынок low-end машин.&lt;/p&gt;
&lt;p&gt;У меня есть пара нетбуков, потому что я люблю маленькие компьютеры и использую их в поездках. Но они никогда не могли бы служить основными машинами для разработки или чем-то вроде этого.&lt;/p&gt;
&lt;p&gt;701 слишком мелкий для того, чтобы быть полезным. Экран крошечный и у него непозволительно маленькое разрешение. Клавиатуру едва можно использовать. 901 намного лучше и мог бы быть неплохим помощником в поездках, но разрешение тоже слишком маленькое (9 дюймов нормально, но 1024&amp;#215;600 юзабельно только для смартфонов, а для лэптопов подошло бы как минимум 1366&amp;#215;768, как мне кажется)&lt;/p&gt;
&lt;p&gt;Поэтому я не использую ни один из них ни для чего, кроме тестирования. 901 используется моей женой для её вышивальной машинки, и для такого, обычного использования он подходит очень хорошо.&lt;/p&gt;
&lt;p&gt;ВНИМАНИЕ! Наверно, следует заметить, что мои требования могут быть завышенными по сравнению с требованиями многих других людей. Моя основная машина — Nehalem 3.2 GHz c 6 GB RAM и двумя быстрыми SSD-дисками от Intel. Поэтому мои представления о том, какая производительность может считаться &amp;#8220;приемлемой&amp;#8221;, могут не совпадать с представлениями других.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: какие задачи Eee PC помогает Вам выполнять?&lt;/strong&gt;&lt;br /&gt;
A: Сейчас 701 работает тестовым стендом для совершенно различных вещей — я держу его поблизости в основном как  32-битный x86-стенд (все мои основные машины — x86-64, поэтому, если мне нужно проверить, что 32 бита еще работают, я использую 701).&lt;/p&gt;
&lt;p&gt;901 я иногда использовал в поездках как лэптоп, и в основном он меня удовлетворял, но, откровенно говоря, существуют нормальные ноутбуки, которые намного-намного-намного лучше.&lt;/p&gt;
&lt;p&gt;Например, я немного поигрался с машинами, основанными на CULV Core 2 Duo (вместо Atom) с экраном 1366&amp;#215;768 и внезапно обнаружил, что может быть намного более мощная &lt;em&gt;(чем eeepc — прим.пер.)&lt;/em&gt; сборка. Она больше по размерам (10 дюймов), потребляет больше энергии, но оно того стоит.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: приобрели ли Вы эти нетбуки самостоятельно или они были подарены?&lt;/strong&gt;&lt;br /&gt;
A: Оба Eee PC были подарены. 10&amp;#8243; CULV Core2 было самым достойным приобретением, на которое я потратил свои деньги.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: сколько времени Вы проводите перед этим нетбуком? Достаточен ли его размер для Вас?&lt;/strong&gt;&lt;br /&gt;
A: См. выше. 701 и близко не стоял. 901 вполне пригоден к использованию, и если бы у него не было такое маленькое разрешение, он мог бы быть неплохим помощником в путешествиях.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: производились ли какие-нибудь аппаратные модификации?&lt;/strong&gt;&lt;br /&gt;
A: в оба добавил памяти, вроде сейчас в обоих по 2 Гб (возможно, 701 был с 512 мегабайтами, и я проапгрейдил до гигабайта, слишком лениво проверять). И еще в оба добавил ПЗУ: в 701 — быструю SD-карточку (понятие &amp;#8220;быстрая&amp;#8221; тут весьма относительно, но для SD-карточки неплохой результат), в 901 — Mini-PCI SSD.&lt;/p&gt;
&lt;p&gt;Мне нравятся high-end SSD (например, &lt;a href="http://torvalds-family.blogspot.com/2008/10/so-i-got-one-of-new-intel-ssds.html"&gt;интеловские замены жестким дискам&lt;/a&gt;), но те, что используются в low-end нетбуках, страдают от ужасающе отвратительной скорости записи. Поэтому SSD в этих нетбуках, как правило, медленнее, чем реальные диски.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Q: и еще один, более общий вопрос. Как Ваше рабочее время распределено между кодированием и административной/политической/социальной деятельностью?&lt;/strong&gt;&lt;br /&gt;
A: Сейчас кодирую очень мало. Практически всё время занято обсуждениями с другими разработчиками и внесением их изменений в ядро.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/SHyAEFgGcsc" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/01/29/linus-about-eeepc.html/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2010/01/29/linus-about-eeepc.html</feedburner:origLink></item>
		<item>
		<title>Линус Торвальдс о машинках для вышивания</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/ZlYbs9aSysI/linus-about-embroidery.html</link>
		<comments>http://bappoy.pp.ru/2010/01/29/linus-about-embroidery.html#comments</comments>
		<pubDate>Fri, 29 Jan 2010 06:11:48 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[linus]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=908</guid>
		<description>&lt;p&gt;&lt;b&gt;Часть первая.&lt;/b&gt;&lt;br /&gt;
На Рождество Санта Клаус подарил Туве Торвальдс  машинку для вышивания. Среди прочих достоинств эта машинка имеет USB-интерфейс, по которому можно закачивать заранее приобретённые шаблоны вышивки в специальном закрытом формате. При подключении к компьютеру это чудо техники через минуту определяется как USB mass storage с файловой системой FAT12,  при этом закачивание небольших файлов происходит очень долго и зачастую не приводит ни к каким результатам: о возникающих ошибках пользователю ничего не сообщается. Таково всё проприетарное ПО, — &lt;a href="http://torvalds-family.blogspot.com/2010/01/embroidery-gaah.html"&gt;сетует&lt;/a&gt; Линус, — закрытые форматы, кривые прошивки, невнятные ошибки&amp;#8230; Проблема предпросмотра шаблонов вышивок в формате PES на компьютере оказалась самой простой и теперь на git.kernel.org имеется специальная программа &lt;a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/pesconvert.git;a=summary"&gt;pesconvert&lt;/a&gt; для обслуживания вышивальных машинок.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Часть вторая.&lt;/b&gt;&lt;br /&gt;
Линус пишет &lt;a href="http://thread.gmane.org/gmane.linux.utilities.util-linux-ng/2888"&gt;письмо&lt;/a&gt; в рассылку util-linux-ng@vger.kernel.org с детальным описанием длительного процесса определения типов разделов и ФС на маленьком, медленном и подглючивающем блочном устройстве. После активного обсуждения (которое, несмотря на явную гиковость, можно читать как захватывающий детектив) было найдено несколько узких мест в  утилите blkid, пытающейся определить более чем 50 типов файловых систем по их сигнатурам, что приводит к неоднократному чтению 69 килобайт с устройства, и в сумме объём прочитанных данных, с учётом упреждающего чтения, составляет около половины объёма всего устройства. Учитывая тот факт, что скорость обмена данными у этой штуки составляет 16  килобайт в секунду, простое определение единственного fat-раздела занимает около 30 секунд (всё это нужно для того, чтобы udev смог корректно примонтировать это устройство).&lt;/p&gt;
&lt;p&gt;Совместными усилиями задержка была сведена к рекордному минимуму в полсекунды. Для этого Karel Zak (главный мейнтейнер util-linux-ng) добавил в blkid несколько опций, ограничивающих количество возможных ФС и объём читаемых данных для очень маленьких устройств (зачем пытаться определить raid на диске размером с полдискеты?), Линус немного оптимизировал кое-какие системные вызовы и теперь в ближайшем выпуске util-linux-ng будет заявлена поддержка очень маленьких дисков, а в ядре Linux, чем черт не шутит — частичная поддержка неких вышивальных машинок.&lt;/p&gt;
&lt;p&gt;Часть третья последует, не пропустите.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/ZlYbs9aSysI" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/01/29/linus-about-embroidery.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2010/01/29/linus-about-embroidery.html</feedburner:origLink></item>
		<item>
		<title>Несколько ссылок по истории computer science</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/t4PNfvk-PVo/computer-sciense-history.html</link>
		<comments>http://bappoy.pp.ru/2010/01/25/computer-sciense-history.html#comments</comments>
		<pubDate>Mon, 25 Jan 2010 12:06:44 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=847</guid>
		<description>&lt;p&gt;Несколько месяцев назад заинтересовался причинами появления управляющих кодов ASCII в их нынешнем виде. Раскопки привели меня к первым терминалам в Multics, терминалы — к телетайпам, телетайпы — к телеграфным аппаратам. Тема чрезвычайно интересная, но полноценного поста у меня так и не вышло по разным причинам. Просто накидаю сюда ссылок для интересующихся (в основном на английском).&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Unix и его предшественники&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.multicians.org/"&gt;Multicians.org&lt;/a&gt; — один из основных сайтов по предыстории Unix. В основном описывает различные аспекты ОС Multics (включая &lt;a href="http://archive.computerhistory.org/resources/text/Honeywell/Honeywell.MulticsSystem.1975.102646162.pdf"&gt;рекламную брошюру&lt;/a&gt; (4 Мб)), но содержит также массу сведений и о ранних вариантах &lt;a href="http://www.multicians.org/unix.html"&gt;Unix&lt;/a&gt;, и о &lt;a href="http://www.multicians.org/thvv/7094.html"&gt;CTSS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.levenez.com/unix/"&gt;Unix history&lt;/a&gt; — основной сайт по истории Unix.&lt;/p&gt;
&lt;p&gt;Концепция иерархической файловой системы &lt;a href="http://www.multicians.org/features.html#tag1.1"&gt;впервые&lt;/a&gt; была &lt;a href="http://www.multicians.org/fjcc4.html"&gt;описана&lt;/a&gt; в 1965 году и сильно отличалась от ныне используемой. В частности, в качестве разделителя каталогово предлагалось использовать двоеточие, а на уровень выше можно было  ссылаться как на &lt;code&gt;*&lt;/code&gt;; у каждого файла присутствовал специальный атрибут TRAP, в котором можно было указать свою процедуру проверки прав доступа к этому файлу. Но уже в Multics реализация файловой системы значительно отличалась от данного проекта иной, а в Unix и вовсе приняла привычный нам вид.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://cm.bell-labs.com/cm/cs/who/dmr/hist.html"&gt;The Evolution of the Unix Time-sharing System&lt;/a&gt; (Dennis M. Ritchie, 1979) — краткая история Unix, рассказанная одним из её создателей.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.usenix.org/events/usenix09/tech/full_papers/toomey/toomey.pdf"&gt;The Restoration of Early UNIX Artifacts&lt;/a&gt; — опыт восстановления файлов с древней ленты, содержащей один из самых первых релизов Unix. В конце документа несколько интересных ссылок.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.bitsavers.org/pdf/bellLabs/unix/PreliminaryUnixImplementationDocument_Jun72.pdf"&gt;Исходный код Unix&lt;/a&gt; — отсканированная распечатка тщательно прокомментированных ассемблерных кодов  Unix. Датируется 1972 годом. 11 мегабайт.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://74.125.77.132/search?q=cache:l4ZThOZLuR0J:searchenterpriselinux.techtarget.com/tip/0,289483,sid39_gci1098161,00.html+http://searchenterpriselinux.techtarget.com/tip/0,289483,sid39_gci1098161,00.html&amp;#038;cd=1&amp;#038;hl=en&amp;#038;ct=clnk"&gt;Excavating ancient abbreviations in Linux&lt;/a&gt; ­— история происхождения некоторых аббревиатур, используемых в UNIX/Linux (для чтения &lt;a href="http://searchenterpriselinux.techtarget.com/tip/0,289483,sid39_gci1098161,00.html"&gt;оригинала&lt;/a&gt; требуется&lt;br /&gt;
регистрация, поэтому ссылка на кэш гугла).&lt;/p&gt;
&lt;p&gt;Буду благодарен за PDF/DJVU версию книги &amp;#8220;A quarter century of Unix&amp;#8221; by Peter Salus :)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Терминалы&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.cs.utk.edu/~shuford/terminal/"&gt;Коллекция информации о текстовых терминалах&lt;/a&gt;, отправная точка исследований.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.multicians.org/terminals.html"&gt;Рассказ одного из создателей Multics о первых терминалах&lt;/a&gt; и опыте удалённой домашней работы (70-е годы, суперкрутые модемы на 1200 бод) (en)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://vt100.net/vt_history"&gt;Краткая история терминалов DEC (в т.ч. VT100)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://foldoc.org/smart+terminal"&gt;Что такое &amp;#8220;smart terminal&amp;#8221;&lt;/a&gt; и чем он отличается от &amp;#8220;dumb terminal&amp;#8221;. В&lt;br /&gt;
основном тем, что умеет проверять пользовательский ввод уже на стороне терминала, а не передаёт его серверу.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Телеграф&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.qrz.ru/articles/article243.html"&gt;К вопросу о возникновении телеграфа&lt;/a&gt; множество интересных сведений из истории телеграфной связи&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.3dnews.ru/editorial/razgovor_tekstom/"&gt;История телеграфа в России&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.amyat.narod.ru/theory/goloveshkin_murashkin_telegrafnoe_delo/index.htm"&gt;Телеграфное дело. Пособие для сержантов и старших специалистов войск связи&lt;/a&gt; — раритет :) Книжка 1946 года выпуска, доступно и понятно описывает теорию электротехники и электроники по состоянию на момент окончания Великой Отечественной войны, а также знакомит читателя с основными понятиями телеграфной связи.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/t4PNfvk-PVo" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/01/25/computer-sciense-history.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2010/01/25/computer-sciense-history.html</feedburner:origLink></item>
		<item>
		<title>Шпаргалка по созданию chroot-окружения в Debian средствами debootstrap</title>
		<link>http://feedproxy.google.com/~r/bappoy/~3/Ha1C_CVR2uE/debian-chroot.html</link>
		<comments>http://bappoy.pp.ru/2010/01/20/debian-chroot.html#comments</comments>
		<pubDate>Wed, 20 Jan 2010 10:49:45 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[chroot]]></category>
		<category><![CDATA[debian]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=845</guid>
		<description>&lt;p&gt;Для тестирования различных версий нашего продукта (внутри — БД под управлением mysql и интерфейс к ней на PHP под Apache2)  требуется быстро создавать многочисленные chroot-окружения на выделенном сервере и управляться с ними. &lt;/p&gt;
&lt;p&gt;В базовой системе (lenny) оставляем только функционал, необходимый для управления всем хозяйством, лично мне необходимы mc, openssh, vim, bash_completion и иногда svn. Также неплохо поиметь где-нибудь (да хоть на этой же машине) кэширующий прокси для репозиториев debian, типа &lt;a href="http://apt-proxy.sourceforge.net/"&gt;apt-proxy&lt;/a&gt; или &lt;a href="http://www.nick-andrew.net/projects/apt-cacher/"&gt;apt-cacher&lt;/a&gt;, чтобы не создавать излишнюю нагрузку на региональные зеркала. У нас используется apt-cacher, работающий по адресу http://apt:3142.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://wiki.debian.org/Debootstrap"&gt;Debootstrap&lt;/a&gt; ­— основная рабочая лошадка:&lt;/p&gt;
&lt;pre&gt;apt-get install debootstrap&lt;/pre&gt;
&lt;pre&gt;debootstrap --include=mc,ssh,vim lenny /systems/lenny http://apt:3142/ftp.debian.org/debian/&lt;/pre&gt;
&lt;p&gt;Первый аргумент — название релиза, второй — путь, куда устанавливается система, третий — адрес репозитория. В опции &amp;#8211;include через запятую указываются пакеты, которые необходимы, но не входят в минимальную базовую систему. Debootstrap выкачивает из репозитория и устанавливает минимальный набор пакетов, теоретически сразу после этого можно делать chroot /systems/lenny и переходить к работе, но осталась еще несколько немаловажных доделок:&lt;/p&gt;
&lt;p&gt;Добавляем идентификатор системы, который будет отображаться в скобках в приглашении шелла (читай — bash), выполняемом в chroot-окружении:&lt;/p&gt;
&lt;pre&gt;echo lenny &gt; /systems/lenny/etc/debian_chroot&lt;/pre&gt;
&lt;p&gt;Но работа в основном ведется от имени root, а в squeeze и sid у root&amp;#8217;а в .bashrc переменная окружения PS1 переопределяется и этот идентификатор пропадает. Поэтому если делаем виртуалку squeeze, то строчку с PS1 в /root/.bashrc лучше закомментировать:&lt;/p&gt;
&lt;pre&gt;sed -i 's/^\(export PS1.*\)$/#\1/g' /systems/&lt;b&gt;&lt;font color="red"&gt;squeeze&lt;/font&gt;&lt;/b&gt;/root/.bashrc&lt;/pre&gt;
&lt;p&gt;Монтируем /dev/pts — виртуальную файловую систему, которая динамически создаёт файлы терминалов /dev/pts/X для каждого нового подключения; это необходимо для нормального функционирования многих программ, работающих с терминалом, в т.ч. скриптов postinst и config пакета mysql-server:&lt;/p&gt;
&lt;pre&gt;mount -t devpts devpts /systems/lenny/dev/pts&lt;/pre&gt;
&lt;p&gt;Монтируем /proc (реально proc в новом месте будет содержать ту же информацию, что и общесистемный /proc):&lt;/p&gt;
&lt;pre&gt;mount -t proc proc /systems/lenny/proc&lt;/pre&gt;
&lt;p&gt;Чтобы apt-get не ругался на неподписанные пакеты при установке, необходимо обновить файл Release.gpg, т.к. по умолчанию debootstrap его не устанавливает. Это проще всего сделать обновлением индексных файлов репозитория:&lt;/p&gt;
&lt;pre&gt;chroot /systems/lenny apt-get update&lt;/pre&gt;
&lt;p&gt;После этого уже можно делать &lt;code&gt;chroot /systems/lenny&lt;/code&gt;, устанавливать и настраивать пакеты, запускать/останавливать сервисы и т.д. Главная проблема при этом ­— следить за тем, чтобы сервисы в разных chroot&amp;#8217;ах не конфликтовали, пытаясь занять порт на одном IP-адресе. Обычно добавляются виртуальные сетевые интерфейсы и им назначаются виртуальные же IP-адреса, которые и указываются в настройках сервисов.&lt;/p&gt;
&lt;p&gt;Disclaimer: данная заметка описывает мой персональный опыт и не претендует на полноту. Комментарии и дополнения приветствуются.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/bappoy/~4/Ha1C_CVR2uE" height="1" width="1"/&gt;</description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/01/20/debian-chroot.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://bappoy.pp.ru/2010/01/20/debian-chroot.html</feedburner:origLink></item>
	</channel>
</rss>

