<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Bappoy&#039;s blog &#187; linux</title>
	<atom:link href="http://bappoy.pp.ru/tag/linux/feed" rel="self" type="application/rss+xml" />
	<link>http://bappoy.pp.ru</link>
	<description>Линуксоид на велосипеде с моторчиком</description>
	<lastBuildDate>Fri, 02 Dec 2011 11:44:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Комфортная работа в Midnight Commander</title>
		<link>http://bappoy.pp.ru/2011/09/08/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><![CDATA[<p>Многие мои коллеги принципиально игнорируют Midnight Commander, предпочитая работать в командной строке. Мотивируют это целым рядом причин, начиная с &laquo;нортон коммандер устарел еще в 1995 году&raquo; и заканчивая &laquo;я юниксоид с 1970 года и без всяких mc прекрасно управляюсь в консоли&raquo;. Конечно же, это дело вкуса, и можно (и нужно!) настроить консоль под себя так, чтобы она летала со скоростью мысли: на помощь приходят команда alias, сочетание Ctrl+R, описание команды shopt в builtins(1), пакет bash_completion или его аналоги, ряд мелких хаков, наподобие <a href="http://bappoy.pp.ru/2008/11/17/quick-call-ssh.html">такого</a>, или альтернатива в виде zsh, в конце концов.</p>
<p>Однако визуалам типа меня удобнее постоянно иметь перед глазами списки файлов и папок, а не помнить, какой файл где находится и что здесь есть еще. Кроме того, пользуясь исключительно командами <code>cd</code> и <code>ls --color</code>, можно легко проглядеть что-нибудь ненужное, типа оставшихся от vim бэкапов в текущем каталоге (если бэкапы нужны, см <code>:help backupdir</code>) или папок с именем из пробела. </p>
<p>Конечно, сначала mc производит немного гнетущее впечатление, но если разобраться и привыкнуть, то может оказаться, что даже с конфигурацией из коробки он очень облегчает жизнь разработчика и системного администратора. Поделюсь собственными хитростями, используемыми каждый день. За кадром осталось еще множество интересных фич, типа кастомной раскраски файлов в панели, смены цветовой схемы на черно-зеленую, сниппетов в редакторе mcedit, настраиваемых VFS, но поскольку я ими не пользуюсь, то ничего про них не скажу. Примеры их настроек и использования можно посмотреть в /etc/mc и в /usr/share/mc.</p>
<p>Сначала полезные мелочи, для многих очевидные.<br />
<!--more--></p>
<ul>
<li>Если до mc по каким-то причинам не доходят коды кнопок Fn, их можно заменить Esc-n. А Alt, иногда перехватываемый панелью меню, успешно заменяется кнопкой Esc
</li>
<li>Режим просмотра файлов «Full file list» лучше, чем «Short file list». При желании можно добавить туда показ прав на объекты файловой системы, например:
<pre>half type name | size | mtime | mode:3</pre>
</li>
<li>Панели подсказок над и под командной строкой внизу и меню сверху можно отключить в Options — Layout, будет больше пространства для списка файлов. Заодно там можно включить отображение свободного места в текущем разделе — очень полезно для нетбуков с мелкими экранами</li>
<li>При навигации по списку файлов сочетание <b>Ctrl+S</b> перекидывает на файл, начинающийся с вводимых символов</li>
<li><b>Alt+Y</b> перекидывает в предыдущую папку. Иногда это бывает полезно при восстановлении после ошибки «The shell is already running the command», за все время существования mc ставшей его визиткой</li>
<li>Встроенный редактор ужасен. В ~/.bashrc добавьте строчку <code>export EDITOR=vim</code>, а в пункте меню Options — Configuration снимите галку «Use internal editor». Точно так же можно использовать переменную окружения PAGER=view для просмотра файлов (опция «Use internal view»)</li>
<li><b>Alt+I</b> покажет текущую папку в противоположной панели, а <b>Alt+O</b> — папку под курсором, а если под курсором файл, то родительскую.</li>
<li>Начиная с ветки midnight commander 4.7.1, в меню сортировки появилась сортировка по версиям, она работает точно так же, как <code>ls -v</code>, т.е. показывает список 1.2.1, 1.2.2, 1.2.10 именно в этом порядке, а не в алфавитном (1.2.1, 1.2.10, 1.2.2). Сам делал :).</li>
<li><b>Ctrl+X c</b> — просмотр и редактирование прав на файл</li>
<li><b>Ctrl+X d</b> — три варианта сравнения двух каталогов: быстрое (по спискам файлов), по размерам (то же самое, только с учетом размеров), полное (по содержимому файлов)</li>
<li><b>Alt+C</b> — быстрый переход в нужную папку без изменения командной строки. По Esc-Tab показывает список подстановки (в командной строке mc Esc-Tab тоже иногда работает)</li>
<li>По <b>Ctrl+\</b> имеется многоуровневое меню быстрого доступа к папкам, в т.ч. и через FTP и SSH. При желании его можно отредактировать вручную в <b>~/.mc/hotlist</b></li>
</ul>
<p>На данный момент самой полезной фичей для меня является пользовательское меню.  Про него я уже писал пару раз (<a href="http://bappoy.pp.ru/2009/06/18/mc-tricks.html">1</a>, <a href="http://bappoy.pp.ru/2011/06/25/mc-unc-path.html">2</a>), сейчас расскажу более подробно.</p>
<p>Я поддерживаю несколько сайтов под mod_perl, и после изменений в коде startup.pl необходимо перезапускать процесс apache, свой для каждого сайта. Каждый сайт находится в /home/sites/sitename, а конфиг apache для этих сайтов — в /usr/local/apache/conf/httpd-sitename.conf.</p>
<p>Когда мне надоело вручную писать /usr/local/apache/bin/apachectl-sitename restart после каждого изменения, в ~/.mc/menu добавились строчки:</p>
<pre>s Restart apache for sitename
   sudo /usr/local/apache/bin/apachectl-sitename restart</pre>
<p>Первая строка задаёт быструю клавишу и название пункта меню, а все за ней следующее — команду, в которой можно использовать ряд макро-подстановок:</p>
<ul>
<li><b>%f</b> — имя файла под курсором, <b>%x</b> — расширение, <b>%b</b> — имя файла без расширения</li>
<li><b>%d</b> — каталог в активной панели, <b>%D</b> — каталог в неактивной панели
</li>
<li><b>%t</b> — выбранные файлы в активной панели, <b>%T</b> — в неактивной</li>
</ul>
<p>и т.д.</p>
<p>Потом появилось еще пять подобных пунктов, для каждого сайта. В конце концов, мне надоело выбирать стрелками нужную команду или искать в длинном списке, какая буква соответствует соответствует нужному пункту. Внимательно перечитав справку, появляющуюся при нажатии F1 в меню F2, добавил еще по строчке к каждому определению пункта меню:</p>
<pre>+= d /home/sites/sitename | f httpd-sitename.conf
s Restart apache for sitename
   sudo /usr/local/apache/bin/apachectl-sitename restart</pre>
<p>Первый символ &laquo;=&raquo; означает начало условия, при котором пункт меню становится активным по умолчанию (при вызове меню курсор уже стоит на этом пункте, так что остаётся только нажать Enter); если перед ним стоит +, то пункт появляется в меню только при выполнении этого условия. Следующий символ — тип условия, например:</p>
<ul>
<li><b>f шаблон</b> — имя файла соответствует шаблону (если в начале файла меню не указана опция shell_patterns=0, то под шаблоном имеется в виду шелл-шаблон, в противном случае — регулярное выражение)</li>
<li><b>d шаблон</b> — текущий каталог соответствует шаблону</li>
<li><b>t type</b> — то, что под курсором, имеет тип:
<ul>
<li>n не является директорией</li>
<li>r обычный файл</li>
<li>d каталог</li>
<li>l ссылка</li>
<li>c последовательное устройство</li>
<li>b блочное устройство</li>
<li>f FIFO</li>
<li>s сокет</li>
<li>x исполняемый файл</li>
<li>t отмеченный файл</li>
</ul>
<p>Различные типы можно комбинировать, например, <code>t rdl</code> означает файл, каталог или ссылку</li>
<li>остальные тесты можно подсмотреть в упомянутой справке</li>
</ul>
<p>Условия можно комбинировать и объединять, например:</p>
<pre>
# если находимся в папке /home/sites/sitename и под курсором — файл .sql, показать этот пункт меню
+= d /home/sites/site_name &amp; f *.sql
S import sql-file to database sitedb
   mysql sitedb &lt; %f
</pre>
<p>Таким образом, приведенный  ранее кусок означает &laquo;если находимся в каталоге сайта или стоим на конфигурационном файле apache для него, показать команду перезапуска сервера и встать на нее курсором&raquo;. </p>
<p>Остальное — дело фантазии и техники. Достаточно подумать о том, какие рутинные действия выполняются достаточно часто, и просто автоматизировать их.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2011/09/08/mc.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Конвертация Unix-style путей в UNC в Midnight Commander</title>
		<link>http://bappoy.pp.ru/2011/06/25/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><![CDATA[<p>Тестовые релизы нашего продукта мы выкладываем в шару \\fs\testing, а готовые сборки и обновления для клиентов — в \\fs\release. У меня эти шары примонтированы соответственно как /mnt/testing и /mnt/release, и при составлении писем о выпуске релиза приходится вручную менять пути вида /mnt/testing/product/version_major/version_minor на \\fs\testing\product\&#8230; </p>
<p>Однажды мне это надоело и я добавил такую запись в ~/.mc/menu:</p>
<pre>+ 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 &#038;</pre>
<p>Теперь, если текущий каталог в Midnight Commander начинается на &laquo;/mnt/&raquo;, в меню F2 появляется пункт &laquo;Convert path to windows format&raquo;, при активации которого в буфер обмена помещается &laquo;правильный&raquo; UNC-путь к текущему каталогу.</p>
<p>О том, почему в Windows используются неправильные слэши, можно узнать из <a href="http://habrahabr.ru/blogs/testing/120652/">этой статьи</a>.</p>
<p><em>Заметка из черновиков годовой давности, сейчас выкладываю другие релизы в другие шары :)</em></p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2011/06/25/mc-unc-path.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Пакетная система Debian: низкоуровневая работа с deb-пакетами</title>
		<link>http://bappoy.pp.ru/2010/10/22/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><![CDATA[<h2>Формат deb-пакета</h2>
<p>Краеугольный камень пакетной системы Debian — это deb-пакет (см. <a href="http://www.opennet.ru/man.shtml?topic=deb&#038;category=5&#038;russian=2">deb(5)</a>), представляющий из себя архив формата <a href="http://sourceware.org/binutils/docs-2.20/binutils/ar.html#ar">ar</a>, внутри которого содержится три файла:<br />
1. debian-binary — текстовый файл, содержащий версию формата deb-пакета, в данный момент это 2.0. Программы, работающие с deb-пакетами, должны читать только первую строку этого файла и не падать, если минорная версия вдруг поменяется (например, станет 2.1).<br />
2. control.tar.gz — служебная информация о пакете, скрипты, вспомогательные файлы (см deb-control(5)). Должен содержать только файлы, единственная папка, которая может присутствовать&nbsp;— &laquo;.&raquo; (текущая директория). В этот архив обязательно должен входить файл control, его минимальное содержимое рассмотрим чуть ниже.<br />
3. data.tar — собственно файлы, устанавливаемые в систему.  Чаще всего этот файл сжат каким-нибудь архиватором (поддерживаются расширения .gz, .xz, .bz2, .lzma), чаще всего в архивах встречается data.tar.gz.<br />
<!--more--><br />
Указанный порядок следования файлов в архиве обязателен. Если в этом архиве требуется разместить еще какие-нибудь файлы (не представляю, зачем это может кому-нибудь понадобиться), они должны находиться перед data.tar.gz, т.е. последний файл в архиве всегда data.tar. Но если сообщество когда-нибудь решит добавить в формат deb еще файлы, они будут помещены после data.tar.</p>
<p>Файл control в архиве control.tar.gz описывает назначение, версию и зависимости пакета, его формат более-менее подробно описан в <a href="http://www.opennet.ru/man.shtml?topic=deb-control&#038;russian=2">deb-control(5)</a>. Пересказывать всю справку сейчас не буду, опишу лишь минимальное содержимое, необходимое для взаимодействия с инфраструктурой dpkg:</p>
<pre>Package: имя пакета
Version: строка версии (при выборе политики назначения версий следует придерживаться <a href="http://manpages.debian.net/cgi-bin/man.cgi?query=deb-version&#038;sektion=&#038;apropos=0&#038;manpath=Debian%205.0%20lenny">deb-version(5)</a>)
Maintainer: John Doe &lt;johndoe@foo.com&gt; (человек, поддерживающий пакет, а не автор программы)
Description: короткое описание пакета
 Длинное описание,  на несколько строк. Каждая строка, входящая в
 длинное описание,  должна начинаться с пробела</pre>
<h2>Работа с пакетами средствами ar</h2>
<p>Теоретически данной информации должно быть достаточно, чтобы собрать простейший пакет &laquo;на коленке&raquo; и установить его в систему. Пусть наш пакет (назовем его test) просто добавляет в систему  файл /usr/share/example-content/test со строчкой &laquo;test&raquo;. Сделаем архив data.tar.gz со структурой папок и единственным файлом, а также файлик debian-binary:</p>
<pre>$ <strong>mkdir -p usr/share/example-content/</strong>
$<strong> echo test &gt; usr/share/example-content/test</strong>
$<strong> tar czf data.tar.gz usr</strong>
$ <strong>echo 2.0 &gt; debian-binary</strong></pre>
<p>Создадим файл <code>control</code> со следующим содержанием:</p>
<pre>$ <strong>cat control</strong>
Package: test
Version: 1.0
Maintainer: Dummy Maint &lt;dummy@example.org&gt;
Description: test package
 Test package created on my own knees.
$ tar czf control.tar.gz control</pre>
<p>Теперь соберем все воедино:</p>
<pre>$ <strong>ar -qS test-1.0.deb debian-binary control.tar.gz data.tar.gz</strong></pre>
<p>В текущем каталоге должен появиться файл <code>test-1.0.deb</code>. Его &laquo;физическое&raquo; содержимое можно просмотреть  с помощью следующей команды:</p>
<pre>$ <strong>ar t test-1.0.deb</strong>
debian-binary
control.tar.gz
data.tar.gz</pre>
<p>Посмотреть файл debian-binary:</p>
<pre>$ <strong>ar p test-1.0.deb debian-binary</strong>
2.0</pre>
<p>Посмотреть список файлов в пакете:</p>
<pre>$ <strong>ar p test-1.0.deb data.tar.gz|tar -tzf -</strong>
usr/
usr/share/
usr/share/example-content/
usr/share/example-content/test</pre>
<p>Посмотреть содержимое файла control:</p>
<pre>$<strong> ar p test-1.0.deb control.tar.gz |tar -O -xzf - control</strong>
Package: test
Version: 1.0
Maintainer: Dummy Maint &lt;dummy@example.org&gt;
Description: test package
 Test package created on my own knees.</pre>
<p>Можно установить этот пакет и убедиться, что файл <code>/usr/share/example-content/test</code> успешно создан, но лучше этого не делать, поскольку из-за недостатка информации в control в пакетной системе может появиться мусор:</p>
<pre>$ <strong>sudo dpkg -i test-1.0.deb</strong>
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) ...</pre>
<h2>Работа с пакетами средствами dpkg-deb</h2>
<p>Все вышеописанное позволяет управляться с deb-пакетами на самом низком уровне, не имея под рукой ничего, кроме стандартных средств Unix (доподлинно известно, что программа ar входила в состав первых Unix 1970х годов). Однако, как несложно догадаться, есть и более высокоуровневые способы создания пакетов и изучения их содержимого. В частности, если уж так необходимо поковыряться с пакетом на низком уровне, все вышеописанные действия настоятельно рекомендуется выполнять с помощью утилиты dpkg-deb(1).</p>
<h3>Создание пакета средствами dpkg-deb</h3>
<p>Минимальный формат вызова команды dpkg-deb для построения пакета следующий:</p>
<pre><strong>dpkg-deb -b исходная_папка</strong></pre>
<p>Все, что находится в исходной папке, кроме директории DEBIAN, помещается в data.tar.gz. Содержимое DEBIAN будет использовано для создания control.tar.gz, в частности, будет прочитан и проанализирован файл control и в случае каких-либо ошибок (отсутствует одно из необходимых полей или эти поля имеют неправильные значения) пакет просто не будет создан. Процесс создания нашего тестового пакета с нуля теперь выглядит так (в последней команде предполагается, что в текущей папке остался файл control от сборки пакета средствами ar):</p>
<p>Подготовка структуры:</p>
<pre><strong>$ mkdir -p test-1.1/usr/share/example-content/ test-1.1/DEBIAN</strong>
$ <strong>echo test 1.1 &gt; test-1.1/usr/share/example-content/test</strong>
$ <strong>sed 's/Version: 1.0/Version: 1.1/g' control &gt; test-1.1/DEBIAN/control</strong></pre>
<p>Попытаемся собрать пакет:</p>
<pre>$ <strong>dpkg-deb -b test-1.1</strong>
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)</pre>
<p>Несмотря на отсутствие важного, но не необходимого поля Architecture, был создан пакет test-1.1.deb. Добавим поле и пересоздадим пакет:</p>
<pre>$ <strong>sed -i "1a \
Architecture: all" test-1.1/DEBIAN/control</strong>
$ <strong>dpkg-deb -b test-1.1</strong>
dpkg-deb: building package `test' in `test-1.1.deb'</pre>
<p>Еще одна немаловажная деталь. Как правило, в названии файла пакета указывается его архитектура, а команда <code>dpkg-deb -b</code> назвала файл по имени папки, из которой он был создан. Если бы папка называлась ololo, то мы получили бы ololo.deb. Чтобы файл пакета автоматически именовался в формате имя-версия-архитектура, при вызове dpkg -b необходимо указывать папку, куда будет положен итоговый архив, например, текущую. Тогда все компоненты имени файла будут извлечены из control:</p>
<pre>$ 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'.</pre>
<p>Теперь всё относительно нормально, продолжаем изучение возможностей dpkg-deb на примере нового пакета.</p>
<h3>Получение информации о пакете</h3>
<p>Узнать версию формата deb, размер пакета и содержимое файла control:</p>
<pre>$ 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 &lt;dummy@example.org&gt;
 Description: test package
  Test package created on my own knees.</pre>
<p>Список файлов, устанавливаемых в систему (кроме служебных):</p>
<pre>$ 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</pre>
<p>Обратите внимание на владельца устанавливаемых файлов и каталогов: это не root, а некий пользователь. Чтобы исправить эту проблему, можно собирать пакеты из-под root&#8217;а, либо воспользоваться специальной утилитой <code>fakeroot</code> из одноименного пакета. Она перехватывает системные вызовы <code>chmod(2)</code> и<code> stat(2)</code> для файлов, и возвращает значения, как если бы файл принадлежал пользователю root. Небольшой пример:</p>
<pre>$ <strong>id</strong>
uid=1000(bvk) gid=1000(bvk) ...
$<strong> touch trololo</strong>
$ <strong>ls -l trololo</strong>
-rw-r--r-- 1 bvk bvk 0 2010-10-22 13:23 trololo
$ <strong>fakeroot ls -l trololo </strong>
-rw-r--r-- 1 root root 0 2010-10-22 13:23 trololo</pre>
<p>Думаю, принцип понятен. Пересоберем пакет еще более правильно:</p>
<pre>$ <strong>fakeroot dpkg -b test-1.1 .</strong>
dpkg-deb: building package `test' in `test_1.1_all.deb'.
$ <strong>dpkg -c test_1.1_all.deb</strong>
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</pre>
<p>Теперь наконец ок.</p>
<p>Можно получаить информацию о пакете в заданном формате:</p>
<pre>$ <strong>dpkg-deb -W --showformat='${Package}-${Version}-${Architecture} (${Maintainer})\n' </strong>test_1.1_all.deb
test-1.1-all (Dummy Maint &lt;dummy@example.org&gt;)</pre>
<p>Список полей, которые можно указать в &#8211;showformat, можно узнать из вывода команды <code>dpkg-deb -I</code></p>
<p>Подать на STDOUT архив data.tar.gz из пакета (уже &laquo;разжатый&raquo;), может быть полезно для извлечения только некоторых файлов:</p>
<pre>$ <strong>dpkg-deb --fsys-tarfile test-1.0.deb |tar -Ox usr/share/example-content/test</strong>
test</pre>
<h2>Перепаковка пакета</h2>
<p>Пожалуй, теперь наступил момент применить свежеполученные знания на практике :) Часто возникает следующая проблема: из некоего источника поступил пакет с некорректными зависимостями, например, требуется устаревший пакет, отсутствующий в системе и всех репозиториях, но доподлинно известно, что другой, уже установленный пакет предоставляет нужную функциональность. В скачанном пакете требуется изменить файл control, убрав или исправив зависимость. Правильно было бы скачать и распаковать исходник пакета (apt-get source), произвести необходимые изменения в скриптах сборки, установить все необходимые для пересборки библиотеки и окружение и т.д. и т.п., но для частного использования (т.е. без распространения по репозиториям) достаточно просто распаковать пакет, изменить необходимые файлы и запаковать обратно. Проиллюстрирую последовательность действий на примере невинного пакета hello:</p>
<pre>$ <strong>aptitude download hello</strong>
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 (если не существует, будет создана):
$ <strong>dpkg-deb -x hello_2.5-1_i386.deb hello</strong>
# распаковать содержимое control.tar.gz в hello/DEBIAN
$ <strong>dpkg-deb -e hello_2.5-1_i386.deb hello/DEBIAN</strong>
# что-нибудь поменять в control, например, версию пакета:
$ <strong>sed -i 's/Version: .*$/Version: 2.5-1test/' hello/DEBIAN/control </strong>
# собрать новый пакет:
$ <strong>fakeroot dpkg -b hello/ .</strong>
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)</pre>
<p>Пакет собран. Убедиться, в том, что  в нем нет ошибок из-за немного нетрадиционного способа сборки, можно с помощью программы lintian:</p>
<pre>$ <strong>sudo aptitude install lintian</strong>
...
$ <strong>lintian hello_2.5-1test_i386.deb</strong>
$ <strong>echo $?</strong>
0</pre>
<p>Всё в порядке!</p>
<p>Об установке пакетов в систему, механизме зависимостей, структуре репозиториев и еще более правильных способах сборки пакетов читайте в следующих статьях :)</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/10/22/low-level-deb.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Следующий месяц в GNU date</title>
		<link>http://bappoy.pp.ru/2010/08/31/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><![CDATA[<p>Если 31 августа спросить у GNU date, какой будет следующий месяц, результат будет немного странным:</p>
<pre>$ 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</pre>
<p>Документация GNU date (см <code>info date Relative items in date strings</code>) специально обращает внимание на эту проблему и рекомендует вычислять следующий месяц не для сегодняшнего числа, а для 15 числа текущего месяца:</p>
<pre>$ date +"%Y-%m" --date "$(date +%Y-%m-15) next month"
2010-09</pre>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/08/31/date-next-month.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Извлечение данных из виртуальных дисков VirtualBox</title>
		<link>http://bappoy.pp.ru/2010/07/21/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><![CDATA[<p>Однажды глубокой ночью мне позарез понадобилось вытащить из остановленной виртуальной машины Virtualbox, находящейся на моем рабочем компьютере, один файлик. Удаленно запустить виртуальную машину и тем более подключиться к ней не получилось, поэтому я решил попробовать вытащить нужный раздел из vdi и смонтировать его. Ситуация немного осложнялась тем, что виртуальный жесткий диск хоть и содержал всего один корневой раздел, но был динамически расширяющимся, а это значит, что блоки файловой системы располагались в хронологическом порядке, а не в том, который ожидает драйвер файловой системы.</p>
<p>К счастью, можно легко преобразовать vdi из динамического формата в статический с помощью многоцелевой утилиты vboxmanage, входящей в состав пакета virtualbox:</p>
<pre>vboxmanage clonehd --variant static debian.vdi temp.vdi</pre>
<p>Теперь у нас есть файл temp.vdi, внутри которого где-то присутствует образ искомой файловой системы; для ее корректного извлечения нужно вычислить смещение образа относительно начала файла. В половине найденных по запросу &laquo;mount vdi linux&raquo; статей рекомендуется использовать для этих целей утилиту vditool, предназначенную на самом деле для внутреннего тестирования функциональности виртуальных дисков в VirtualBox. Раньше бинарник vditool можно было отдельно скачать с сайта virtualbox.org, но теперь его там по понятным причинам нет (желающие могут скомпилировать его самостоятельно: <a href="http://www.virtualbox.org/browser/trunk/src/VBox/Devices/Storage/testcase/vditool.cpp">vditool.cpp</a>) </p>
<p>Мы, как всегда, пойдем другим путем и воспользуемся подручными средствами. Первые 512 байт нашего vdi-файла — его заголовок, в котором можно разобраться, воспользовавшись, например, <a href="http://forums.virtualbox.org/viewtopic.php?p=29267&#038;sid=f13e432626fbf4b62807f7eb6fde8345#p292678">этим мануалом</a> или непосредственно описанием <a href="http://www.virtualbox.org/browser/trunk/src/VBox/Devices/Storage/VDICore.h#L135">структуры заголовка vdi</a> в исходниках VirtualBox. Из этих источников следует, что образ размечен следующим образом:<br />
512 байт: заголовок<br />
4 * N + X: карта мегабайтных блоков, здесь N ­— количество мегабайт в виртуальном жестком диске, а X — выравнивание получившегося числа до ближайшей верхней 512-байтной границы<br />
512 + 4*N + выравнивание: смещение данных</p>
<p>Зная точный размер виртуального диска, можно легко вычислить смещение вручную:</p>
<pre>$ 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
</pre>
<p>(UUID нужного диска можно узнать из вывода команды vboxmanage list hhds). Здесь выравненное до 512 значение размера карты блоков равно 16384, а смещение данных — 16896.<br />
А можно и вытащить смещение непосредственно из заголовка vdi. Например, вот начало моего четырёхгигового виртуального диска:</p>
<pre>$ head -c 512 temp.vdi |hexdump  -C
00000000  3c 3c 3c 20 53 75 6e 20  56 69 72 74 75 61 6c 42  |&lt; &lt;&lt; Sun VirtualB|
00000010  6f 78 20 44 69 73 6b 20  49 6d 61 67 65 20 3e 3e  |ox Disk Image &gt;&gt;|
00000020  3e 0a 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |&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  <b>00 42 00 00</b> 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?.&lt;f7l ....@|
000001a0  a7 63 44 3f 6e 3f 26 d8  00 00 00 00 00 00 00 00  |.cD?n?&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</pre>
<p>Жирным шрифтом выделены необходимые четыре байта offsetData по смещению 0&#215;0158. Можно искать их визуально, помня о little-endian-порядке байт (в этом случае искомое значение равно 0&#215;00004200), а можно воспользоваться простенькой командой:</p>
<pre>$ head -c 348 temp.vdi |tail -c 4|perl -ne 'print unpack("L",$_),"\n"'
16896</pre>
<p>В любом случае, лишний раз перепроверить себя никогда не помешает.</p>
<p>Посмотрим, что находится по этому смещению. Сразу можно предположить, что там располагается начало образа жесткого диска, из этого следует, что первые 512 байт содержат mbr. Проверим:</p>
<pre>$ 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</pre>
<p>Жесткий диск содержит 2 раздела: основной размером 3859 мегабайт, начинающийся с 63 сектора (1 сектор — 512 байт), и расширенный 235 мегабайт, отведенный установщиком Debian под swap (вот это сюрприз на виртуалке). Для очистки совести проверяем заголовок первого раздела:</p>
<pre>$ 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)</pre>
<p>То, что надо! Осталось смонтировать. Несколько лет назад пришлось бы дополнительно извлекать все 7903917 секторов в отдельный файл и монтировать его, но сейчас можно просто указать смещение от начала файла как опцию mount (оставшиеся расширенный раздел и swap внутри него будут проигнорированы):</p>
<pre>$ 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</pre>
<p>Задача решена, все свободны.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/07/21/mount-fs-from-vdi.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Линус Торвальдс о Eee PC</title>
		<link>http://bappoy.pp.ru/2010/01/29/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><![CDATA[<p>В предыдущем посте — <a href="http://bappoy.pp.ru/2010/01/29/linus-about-embroidery.html">небольшая история</a> о том, как в Linux была улучшена поддержка устройств экстра-маленького размера благодаря покупки Линусом Торвальдсом вышивальной машинки :) В <a href="http://article.gmane.org/gmane.linux.utilities.util-linux-ng/2888">письме Линуса</a> в рассылку util-linux-ng@kernel.org было упомянуто, что для управления этой машинкой он использует Eee PC с Fedora 12 на борту. Как <a href="http://bappoy.pp.ru/2008/05/06/eee-first-impressions.html">пользователь Eee PC 701g</a> с почти двухлетним стажем, я заинтересовался и написал Линусу письмо с несколькими вопросами о его опыте использования этих компьютеров. Получилось мини-интервью, которое и предлагается вашему вниманию.</p>
<p><strong>Q: Какие модели Eee PC Вы используете?</strong><br />
A: У меня их две штуки: 701 и 901.</p>
<p>Q: Это основной компьютер или один из дополнительных?<br />
A: Нет, конечно же, это не основной компьютер. Atom тормозной как грех. Я считаю, что процессоры с прямым выполнением команд (in-order execution) — преступление против человечности, и я уверен в том, что если Intel не предпримет значительных шагов (т.е. сделает Atom <a href="http://en.wikipedia.org/wiki/Out-of-order_execution">out-of-order</a>), ARM Cortex A9 захватит рынок low-end машин.</p>
<p>У меня есть пара нетбуков, потому что я люблю маленькие компьютеры и использую их в поездках. Но они никогда не могли бы служить основными машинами для разработки или чем-то вроде этого.</p>
<p>701 слишком мелкий для того, чтобы быть полезным. Экран крошечный и у него непозволительно маленькое разрешение. Клавиатуру едва можно использовать. 901 намного лучше и мог бы быть неплохим помощником в поездках, но разрешение тоже слишком маленькое (9 дюймов нормально, но 1024&#215;600 юзабельно только для смартфонов, а для лэптопов подошло бы как минимум 1366&#215;768, как мне кажется)</p>
<p>Поэтому я не использую ни один из них ни для чего, кроме тестирования. 901 используется моей женой для её вышивальной машинки, и для такого, обычного использования он подходит очень хорошо.</p>
<p>ВНИМАНИЕ! Наверно, следует заметить, что мои требования могут быть завышенными по сравнению с требованиями многих других людей. Моя основная машина — Nehalem 3.2 GHz c 6 GB RAM и двумя быстрыми SSD-дисками от Intel. Поэтому мои представления о том, какая производительность может считаться &laquo;приемлемой&raquo;, могут не совпадать с представлениями других.</p>
<p><strong>Q: какие задачи Eee PC помогает Вам выполнять?</strong><br />
A: Сейчас 701 работает тестовым стендом для совершенно различных вещей — я держу его поблизости в основном как  32-битный x86-стенд (все мои основные машины — x86-64, поэтому, если мне нужно проверить, что 32 бита еще работают, я использую 701).</p>
<p>901 я иногда использовал в поездках как лэптоп, и в основном он меня удовлетворял, но, откровенно говоря, существуют нормальные ноутбуки, которые намного-намного-намного лучше.</p>
<p>Например, я немного поигрался с машинами, основанными на CULV Core 2 Duo (вместо Atom) с экраном 1366&#215;768 и внезапно обнаружил, что может быть намного более мощная <em>(чем eeepc — прим.пер.)</em> сборка. Она больше по размерам (10 дюймов), потребляет больше энергии, но оно того стоит.</p>
<p><strong>Q: приобрели ли Вы эти нетбуки самостоятельно или они были подарены?</strong><br />
A: Оба Eee PC были подарены. 10&#8243; CULV Core2 было самым достойным приобретением, на которое я потратил свои деньги.</p>
<p><strong>Q: сколько времени Вы проводите перед этим нетбуком? Достаточен ли его размер для Вас?</strong><br />
A: См. выше. 701 и близко не стоял. 901 вполне пригоден к использованию, и если бы у него не было такое маленькое разрешение, он мог бы быть неплохим помощником в путешествиях.</p>
<p><strong>Q: производились ли какие-нибудь аппаратные модификации?</strong><br />
A: в оба добавил памяти, вроде сейчас в обоих по 2 Гб (возможно, 701 был с 512 мегабайтами, и я проапгрейдил до гигабайта, слишком лениво проверять). И еще в оба добавил ПЗУ: в 701 — быструю SD-карточку (понятие &laquo;быстрая&raquo; тут весьма относительно, но для SD-карточки неплохой результат), в 901 — Mini-PCI SSD.</p>
<p>Мне нравятся high-end SSD (например, <a href="http://torvalds-family.blogspot.com/2008/10/so-i-got-one-of-new-intel-ssds.html">интеловские замены жестким дискам</a>), но те, что используются в low-end нетбуках, страдают от ужасающе отвратительной скорости записи. Поэтому SSD в этих нетбуках, как правило, медленнее, чем реальные диски.</p>
<p><strong>Q: и еще один, более общий вопрос. Как Ваше рабочее время распределено между кодированием и административной/политической/социальной деятельностью?</strong><br />
A: Сейчас кодирую очень мало. Практически всё время занято обсуждениями с другими разработчиками и внесением их изменений в ядро.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/01/29/linus-about-eeepc.html/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Линус Торвальдс о машинках для вышивания</title>
		<link>http://bappoy.pp.ru/2010/01/29/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><![CDATA[<p><b>Часть первая.</b><br />
На Рождество Санта Клаус подарил Туве Торвальдс  машинку для вышивания. Среди прочих достоинств эта машинка имеет USB-интерфейс, по которому можно закачивать заранее приобретённые шаблоны вышивки в специальном закрытом формате. При подключении к компьютеру это чудо техники через минуту определяется как USB mass storage с файловой системой FAT12,  при этом закачивание небольших файлов происходит очень долго и зачастую не приводит ни к каким результатам: о возникающих ошибках пользователю ничего не сообщается. Таково всё проприетарное ПО, — <a href="http://torvalds-family.blogspot.com/2010/01/embroidery-gaah.html">сетует</a> Линус, — закрытые форматы, кривые прошивки, невнятные ошибки&#8230; Проблема предпросмотра шаблонов вышивок в формате PES на компьютере оказалась самой простой и теперь на git.kernel.org имеется специальная программа <a href="http://git.kernel.org/?p=linux/kernel/git/torvalds/pesconvert.git;a=summary">pesconvert</a> для обслуживания вышивальных машинок.</p>
<p><b>Часть вторая.</b><br />
Линус пишет <a href="http://thread.gmane.org/gmane.linux.utilities.util-linux-ng/2888">письмо</a> в рассылку util-linux-ng@vger.kernel.org с детальным описанием длительного процесса определения типов разделов и ФС на маленьком, медленном и подглючивающем блочном устройстве. После активного обсуждения (которое, несмотря на явную гиковость, можно читать как захватывающий детектив) было найдено несколько узких мест в  утилите blkid, пытающейся определить более чем 50 типов файловых систем по их сигнатурам, что приводит к неоднократному чтению 69 килобайт с устройства, и в сумме объём прочитанных данных, с учётом упреждающего чтения, составляет около половины объёма всего устройства. Учитывая тот факт, что скорость обмена данными у этой штуки составляет 16  килобайт в секунду, простое определение единственного fat-раздела занимает около 30 секунд (всё это нужно для того, чтобы udev смог корректно примонтировать это устройство).</p>
<p>Совместными усилиями задержка была сведена к рекордному минимуму в полсекунды. Для этого Karel Zak (главный мейнтейнер util-linux-ng) добавил в blkid несколько опций, ограничивающих количество возможных ФС и объём читаемых данных для очень маленьких устройств (зачем пытаться определить raid на диске размером с полдискеты?), Линус немного оптимизировал кое-какие системные вызовы и теперь в ближайшем выпуске util-linux-ng будет заявлена поддержка очень маленьких дисков, а в ядре Linux, чем черт не шутит — частичная поддержка неких вышивальных машинок.</p>
<p>Часть третья последует, не пропустите.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/01/29/linus-about-embroidery.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Несколько ссылок по истории computer science</title>
		<link>http://bappoy.pp.ru/2010/01/25/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><![CDATA[<p>Несколько месяцев назад заинтересовался причинами появления управляющих кодов ASCII в их нынешнем виде. Раскопки привели меня к первым терминалам в Multics, терминалы — к телетайпам, телетайпы — к телеграфным аппаратам. Тема чрезвычайно интересная, но полноценного поста у меня так и не вышло по разным причинам. Просто накидаю сюда ссылок для интересующихся (в основном на английском).</p>
<p><b>Unix и его предшественники</b><br />
<a href="http://www.multicians.org/">Multicians.org</a> — один из основных сайтов по предыстории Unix. В основном описывает различные аспекты ОС Multics (включая <a href="http://archive.computerhistory.org/resources/text/Honeywell/Honeywell.MulticsSystem.1975.102646162.pdf">рекламную брошюру</a> (4 Мб)), но содержит также массу сведений и о ранних вариантах <a href="http://www.multicians.org/unix.html">Unix</a>, и о <a href="http://www.multicians.org/thvv/7094.html">CTSS</a>.</p>
<p><a href="http://www.levenez.com/unix/">Unix history</a> — основной сайт по истории Unix.</p>
<p>Концепция иерархической файловой системы <a href="http://www.multicians.org/features.html#tag1.1">впервые</a> была <a href="http://www.multicians.org/fjcc4.html">описана</a> в 1965 году и сильно отличалась от ныне используемой. В частности, в качестве разделителя каталогово предлагалось использовать двоеточие, а на уровень выше можно было  ссылаться как на <code>*</code>; у каждого файла присутствовал специальный атрибут TRAP, в котором можно было указать свою процедуру проверки прав доступа к этому файлу. Но уже в Multics реализация файловой системы значительно отличалась от данного проекта иной, а в Unix и вовсе приняла привычный нам вид.</p>
<p><a href="http://cm.bell-labs.com/cm/cs/who/dmr/hist.html">The Evolution of the Unix Time-sharing System</a> (Dennis M. Ritchie, 1979) — краткая история Unix, рассказанная одним из её создателей.</p>
<p><a href="https://www.usenix.org/events/usenix09/tech/full_papers/toomey/toomey.pdf">The Restoration of Early UNIX Artifacts</a> — опыт восстановления файлов с древней ленты, содержащей один из самых первых релизов Unix. В конце документа несколько интересных ссылок.</p>
<p><a href="http://www.bitsavers.org/pdf/bellLabs/unix/PreliminaryUnixImplementationDocument_Jun72.pdf">Исходный код Unix</a> — отсканированная распечатка тщательно прокомментированных ассемблерных кодов  Unix. Датируется 1972 годом. 11 мегабайт.</p>
<p><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&#038;cd=1&#038;hl=en&#038;ct=clnk">Excavating ancient abbreviations in Linux</a> ­— история происхождения некоторых аббревиатур, используемых в UNIX/Linux (для чтения <a href="http://searchenterpriselinux.techtarget.com/tip/0,289483,sid39_gci1098161,00.html">оригинала</a> требуется<br />
регистрация, поэтому ссылка на кэш гугла).</p>
<p>Буду благодарен за PDF/DJVU версию книги &laquo;A quarter century of Unix&raquo; by Peter Salus :)</p>
<p><b>Терминалы</b><br />
<a href="http://www.cs.utk.edu/~shuford/terminal/">Коллекция информации о текстовых терминалах</a>, отправная точка исследований.</p>
<p><a href="http://www.multicians.org/terminals.html">Рассказ одного из создателей Multics о первых терминалах</a> и опыте удалённой домашней работы (70-е годы, суперкрутые модемы на 1200 бод) (en)</p>
<p><a href="http://vt100.net/vt_history">Краткая история терминалов DEC (в т.ч. VT100)</a></p>
<p><a href="http://foldoc.org/smart+terminal">Что такое &laquo;smart terminal&raquo;</a> и чем он отличается от &laquo;dumb terminal&raquo;. В<br />
основном тем, что умеет проверять пользовательский ввод уже на стороне терминала, а не передаёт его серверу.</p>
<p><b>Телеграф</b><br />
<a href="http://www.qrz.ru/articles/article243.html">К вопросу о возникновении телеграфа</a> множество интересных сведений из истории телеграфной связи</p>
<p><a href="http://www.3dnews.ru/editorial/razgovor_tekstom/">История телеграфа в России</a></p>
<p><a href="http://www.amyat.narod.ru/theory/goloveshkin_murashkin_telegrafnoe_delo/index.htm">Телеграфное дело. Пособие для сержантов и старших специалистов войск связи</a> — раритет :) Книжка 1946 года выпуска, доступно и понятно описывает теорию электротехники и электроники по состоянию на момент окончания Великой Отечественной войны, а также знакомит читателя с основными понятиями телеграфной связи.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/01/25/computer-sciense-history.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Шпаргалка по созданию chroot-окружения в Debian средствами debootstrap</title>
		<link>http://bappoy.pp.ru/2010/01/20/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><![CDATA[<p>Для тестирования различных версий нашего продукта (внутри — БД под управлением mysql и интерфейс к ней на PHP под Apache2)  требуется быстро создавать многочисленные chroot-окружения на выделенном сервере и управляться с ними. </p>
<p>В базовой системе (lenny) оставляем только функционал, необходимый для управления всем хозяйством, лично мне необходимы mc, openssh, vim, bash_completion и иногда svn. Также неплохо поиметь где-нибудь (да хоть на этой же машине) кэширующий прокси для репозиториев debian, типа <a href="http://apt-proxy.sourceforge.net/">apt-proxy</a> или <a href="http://www.nick-andrew.net/projects/apt-cacher/">apt-cacher</a>, чтобы не создавать излишнюю нагрузку на региональные зеркала. У нас используется apt-cacher, работающий по адресу http://apt:3142.</p>
<p><a href="http://wiki.debian.org/Debootstrap">Debootstrap</a> ­— основная рабочая лошадка:</p>
<pre>apt-get install debootstrap</pre>
<pre>debootstrap --include=mc,ssh,vim lenny /systems/lenny http://apt:3142/ftp.debian.org/debian/</pre>
<p>Первый аргумент — название релиза, второй — путь, куда устанавливается система, третий — адрес репозитория. В опции &#8211;include через запятую указываются пакеты, которые необходимы, но не входят в минимальную базовую систему. Debootstrap выкачивает из репозитория и устанавливает минимальный набор пакетов, теоретически сразу после этого можно делать chroot /systems/lenny и переходить к работе, но осталась еще несколько немаловажных доделок:</p>
<p>Добавляем идентификатор системы, который будет отображаться в скобках в приглашении шелла (читай — bash), выполняемом в chroot-окружении:</p>
<pre>echo lenny > /systems/lenny/etc/debian_chroot</pre>
<p>Но работа в основном ведется от имени root, а в squeeze и sid у root&#8217;а в .bashrc переменная окружения PS1 переопределяется и этот идентификатор пропадает. Поэтому если делаем виртуалку squeeze, то строчку с PS1 в /root/.bashrc лучше закомментировать:</p>
<pre>sed -i 's/^\(export PS1.*\)$/#\1/g' /systems/<b><font color="red">squeeze</font></b>/root/.bashrc</pre>
<p>Монтируем /dev/pts — виртуальную файловую систему, которая динамически создаёт файлы терминалов /dev/pts/X для каждого нового подключения; это необходимо для нормального функционирования многих программ, работающих с терминалом, в т.ч. скриптов postinst и config пакета mysql-server:</p>
<pre>mount -t devpts devpts /systems/lenny/dev/pts</pre>
<p>Монтируем /proc (реально proc в новом месте будет содержать ту же информацию, что и общесистемный /proc):</p>
<pre>mount -t proc proc /systems/lenny/proc</pre>
<p>Чтобы apt-get не ругался на неподписанные пакеты при установке, необходимо обновить файл Release.gpg, т.к. по умолчанию debootstrap его не устанавливает. Это проще всего сделать обновлением индексных файлов репозитория:</p>
<pre>chroot /systems/lenny apt-get update</pre>
<p>После этого уже можно делать <code>chroot /systems/lenny</code>, устанавливать и настраивать пакеты, запускать/останавливать сервисы и т.д. Главная проблема при этом ­— следить за тем, чтобы сервисы в разных chroot&#8217;ах не конфликтовали, пытаясь занять порт на одном IP-адресе. Обычно добавляются виртуальные сетевые интерфейсы и им назначаются виртуальные же IP-адреса, которые и указываются в настройках сервисов.</p>
<p>Disclaimer: данная заметка описывает мой персональный опыт и не претендует на полноту. Комментарии и дополнения приветствуются.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/01/20/debian-chroot.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Как не пропустить момент установки нового ядра с помощью команды watch</title>
		<link>http://bappoy.pp.ru/2010/01/13/watch.html</link>
		<comments>http://bappoy.pp.ru/2010/01/13/watch.html#comments</comments>
		<pubDate>Wed, 13 Jan 2010 16:52:33 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[humor]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=886</guid>
		<description><![CDATA[<p>Выдержка из <code>man 1 watch</code> (входит в комплект утилит procps в Debian Lenny):</p>
<pre>You can watch for your administrator to install the latest kernel with

        watch uname -r

(Note that <u>-p</u> isn’t guaranteed to work across reboots, especially
in the face of <b>ntpdate</b> or other bootup time-changing mechanisms)</pre>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2010/01/13/watch.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Разделение аргументов в shebang</title>
		<link>http://bappoy.pp.ru/2009/12/28/shebang-args.html</link>
		<comments>http://bappoy.pp.ru/2009/12/28/shebang-args.html#comments</comments>
		<pubDate>Sun, 27 Dec 2009 20:29:25 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[shebang]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=870</guid>
		<description><![CDATA[<p>В <a href="http://bappoy.pp.ru/2008/12/29/bash-pitfalls-part05.html#comment-8577">комментариях</a> к прошлогоднему <a href="http://bappoy.pp.ru/tag/bash-pitfalls">переводу Bash Pitfalls</a> внимательный <b>flavi</b> задался вопросом, почему при попытке выполнить скрипт, в начале которого написано </p>
<pre>#!/bin/bash --posix --verbose</pre>
<p>выдаётся ошибка </p>
<pre>/bin/bash: --posix --verbose: invalid option</pre>
<p>в то время как в интерактивном режиме bash нормально запускается с такой комбинацией опций; более того, если в shebang&#8217;е оставить только одну из этих опций, то скрипт также запускается без ошибок.</p>
<p>Поначалу я предположил, что <code>--posix</code> запрещает    опции, не определённые <a href="http://www.opengroup.org/onlinepubs/009695399/utilities/sh.html">стандартом POSIX на sh</a>. Но тогда попытка выполнить <code>bash --posix --norc</code> также приводила бы к ошибке, и конструкция <code>#!/bin/bash --verbose --norc</code> работала бы нормально, а это не так.</p>
<p>Пришлось разбираться более плотно. В <code>bash (1)</code> я вычитал следующее (выделение — моё):</p>
<blockquote><p>If the program is a file beginning with #!, the remainder of the first line specifies an interpreter for the  program.  The shell executes the specified interpreter on operating systems that do not handle this  executable format themselves.  The arguments to the interpreter consist of a  <b>single</b><b>  optional  argument  following  the  interpreter  name on the first line of the program, followed by the name of the program, followed by the command arguments, if any.</b></p></blockquote>
<p>Т.е. в shebang можно задавать только один аргумент; кроме того, bash самостоятельно анализирует shebang и вызывает указанный интерпретатор только в случае, если система сама не может выполнить этот скрипт.</p>
<p>Сам файл передаётся на выполнение с помощью системного вызова <code>execve (2)</code> (это я вычитал в файле <code>execute_cmd.c</code> в исходном коде bash), в man-странице которого и разъясняется политика партии по поводу разбиения аргументов интерпретатора:</p>
<blockquote><p>On Linux, the entire string following the interpreter name is passed as a single argument  to  the  interpreter, and this string can include white space.</p></blockquote>
<p>Таким образом, в самом первом примере у bash в argv оказывается  не два аргумента <code>--verbose</code> и <code>--norc</code>, а  один <code>--verbose --norc</code>, что и приводит к ошибке, и вина bash лишь в том, что он не разбивает свои аргументы на части, как это делает, например, Perl.</p>
<p>Причина такого странного поведения операционной системы (казалось бы, что сложного в том, чтобы просто разбить строку на части по пробелам или символам табуляции) описана, например, <a href="http://lkml.indiana.edu/hypermail/linux/kernel/0812.0/02503.html">в этой дискуссии LKML</a> или, более подробно, в <a href="http://unix.derkeiler.com/Mailing-Lists/FreeBSD/arch/2005-02/0039.html">письме Garance A Drosihn</a> в рассылку freebsd-arch. Вкратце, если бы механизм механизм обработки shebang (в Linux — <a href="http://lxr.linux.no/#linux+v2.6.32/fs/binfmt_script.c">linux/fs/binfmt_script.c</a>) передавал все аргументы интерпретатору, то для некоторых из них было бы затруднительно отделить аругменты интерпретатора от собственно аргументов  вызываемого скрипта. По крайней мере, так было еще на заре развития Unix и с тех пор <a href="http://www.in-ulm.de/~mascheck/various/shebang/#results">большая часть Unix-систем</a> передаёт все аргументы как единую строку.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2009/12/28/shebang-args.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Басни про git</title>
		<link>http://bappoy.pp.ru/2009/12/27/git.html</link>
		<comments>http://bappoy.pp.ru/2009/12/27/git.html#comments</comments>
		<pubDate>Sat, 26 Dec 2009 22:19:50 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/2009/12/27/%d0%b1%d0%b0%d1%81%d0%bd%d1%8f-%d0%bf%d1%80%d0%be-git.html</guid>
		<description><![CDATA[<p>Пытающимся отвыкнуть от идеологии CVS и SVN —  <a href="http://hades.name/blog/2009/05/23/the-git-parable-ru/">рассказ о концепциях распределённых систем контроля версий</a>.</p>
<p><a href="http://los-t.livejournal.com/tag/git+guts">Более подробное введение</a></p>
<p><font size=small>ага, для ссылок есть твиттер и del.icio.us, но ЭТУ ссылку я уже однажды потерял. Так что пусть тут побудет, в назидание.</font></p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2009/12/27/git.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Заметки на память</title>
		<link>http://bappoy.pp.ru/2009/09/07/782.html</link>
		<comments>http://bappoy.pp.ru/2009/09/07/782.html#comments</comments>
		<pubDate>Mon, 07 Sep 2009 10:34:37 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[keyboard]]></category>
		<category><![CDATA[mount]]></category>
		<category><![CDATA[samba]]></category>
		<category><![CDATA[su]]></category>
		<category><![CDATA[sudo]]></category>
		<category><![CDATA[syslog]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=782</guid>
		<description><![CDATA[<p>Если после перезагрузки не сохраняются параметры клавиатуры в Gnome-окружении Debian или Ubuntu, поможет добавление <strong>setxkbmap</strong> в приложения, запускаемые автоматически при входе в систему (&laquo;Система — Параметры — Запускаемые приложения&raquo; или &laquo;System — Parameters — Sessions&raquo;)</p>
<p>Если при монтировании расшаренного через Samba каталога через mount.cifs симлинки отображаются как локальные ссылки, нужно на обеих машинах в <strong>smb.conf</strong> отключить unix extensions, которые и отвечают за такое поведение символических ссылок:</p>
<pre>unix extensions = no</pre>
<p>Если в Ubuntu одновременно перестали работать su, sudo, входы в систему с консоли и через ssh (основной симптом: зависает после ввода пароля), то для постановки окончательного дифференциального диагноза можно попробовать выполнить команду &laquo;logger test&raquo;. Если и это зависает, то налицо проблема с демоном syslogd. В моем случае решение вылилось в отключении опции &laquo;<strong>-r</strong>&raquo; в<strong>/etc/default/syslogd</strong> (принимать сообщения по сети), которая однажды была добавлена мной для удаленной отладки одного voip-телефона. На самом деле это явная бага, которая, судя по <a href="https://bugs.launchpad.net/ubuntu/+source/sysklogd/+bug/26986">Ubuntu Bug 26986</a>, тянется аж с 2005 года.</p>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2009/09/07/782.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ссылка на определенное место в man&#8217;е</title>
		<link>http://bappoy.pp.ru/2009/08/24/reference-to-fragment-in-less.html</link>
		<comments>http://bappoy.pp.ru/2009/08/24/reference-to-fragment-in-less.html#comments</comments>
		<pubDate>Mon, 24 Aug 2009 10:04:53 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[less]]></category>
		<category><![CDATA[tips]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=773</guid>
		<description><![CDATA[<p>В блоге <a href="http://linsovet.com/">&laquo;Полезные советы по Linux&raquo;</a> <a href="http://linsovet.com/zsh-vcs-info-in-prompt">наткнулся</a> на способ ссылаться на определенное место в документации:</p>
<pre>sh -c 'PAGER="less" LESS="-p search_string" man man_page'</pre>
<p>Явно вызываем sh, задаем просмотрщик less и указываем ему строку, которую нужно найти. Команда man запустит less и прокрутит экран до первого совпадения.</p>
<p>Конечно же, необходимо убедиться, что заданный шаблон присутствует в документе хотя бы один раз, и первый раз встречается именно в том месте, на которое вы хотите сослаться. Если ни одного совпадения не найдено, будет выведена ошибка и man будет показан с его начала, да и то только после нажатия Enter. Также стоит учитывать, что у адресата вашего сообщения может быть другой shell, другая версия документации и вообще другая операционная система.</p>
<p>Несколько примеров (предполагаем, что в качестве шелла используется sh-compatible shell типа bash или zsh, а переменная PAGER установлена в less).</p>
<p>Абзац в bash (1) про фичу <b>complete-into-braces</b> из одной из предыдущих заметок:</p>
<pre>LESS="-p complete-into-braces" man bash</pre>
<p>Раздел про подстановку из истории в bash (1). Поскольку строка HISTORY EXPANSION в документе встречается неоднократно, то требуется привязка к началу строки:</p>
<pre>LESS='-p ^s*HISTORY EXPANSION' man bash</pre>
<p>Подсветка важной фразы целиком:</p>
<pre>LESS='-p Please note.*log the command[^.]*.' man sudo</pre>
<p>Этот фокус можно задействовать в других утилитах, использующих less, например, в perldoc:</p>
<pre>LESS='-p ^s*Range Operators' perldoc perlop</pre>
<p>О том, как эта конструкция работает:</p>
<pre>LESS='-p MANPAGER, PAGER' man man
LESS='-p -ppattern.*' man less
LESS='-p Options which.*' man less</pre>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2009/08/24/reference-to-fragment-in-less.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Мелкие хитрости midnight commander</title>
		<link>http://bappoy.pp.ru/2009/06/18/mc-tricks.html</link>
		<comments>http://bappoy.pp.ru/2009/06/18/mc-tricks.html#comments</comments>
		<pubDate>Thu, 18 Jun 2009 17:12:20 +0000</pubDate>
		<dc:creator>bappoy</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[mc]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[vimdiff]]></category>

		<guid isPermaLink="false">http://bappoy.pp.ru/?p=708</guid>
		<description><![CDATA[<p>Из /usr/share/doc/mc/README.Debian:<br />
- если в истории команд mc постоянно присутствуют строки вида <code>cd "`printf "%b" '\0057home'`"</code>, убедитесь, что в переменной окружения <code>HISTCONTROL</code> присутствует ignorespace или ignoreboth, или же эта переменная вообще отсутствует. Подробности в <a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=440102">debian bug 440102</a>.<br />
- действие, с незапамятных времен выполнявшееся по кнопкам M-O (в противоположной панели отобразить путь в текущей панели), с 4.6.2-pre1 пор переехало на M-I, а на M-O теперь отображение в другой панели родительского каталога, или каталога, находящегося под курсором. Эргономично, да, но очень непривычно. Кстати, русскоязычная справка, вызываемая по F1, описывает старое поведение. </p>
<hr />
У нас есть несколько папок с однотипными объектами вида 1.1.1.1, 1.1.1.2, &#8230;, 1.1.1.10, 1.1.1.11, &#8230;, 1.4.3.5, 1.4.3.9, 1.4.3.10 &#8230;. Опытные разработчики уже, наверно, догадались, к чему я клоню :) При обычной алфавитно-цифровой сортировке 1.1.1.10 следует после 1.1.1.1, но до 1.1.1.2, что очень неприятно. У GNU-версии ls есть специальная опция -v, которая как раз выводит файлы в порядке возрастания версий. А в mc ничего похожего, увы, нет.</p>
<p>За 10 минут сделал <a href="http://mc.redhat-club.org/cms/forum/viewthread.php?thread_id=146">патч</a>, добавляющий вариант &laquo;сортировать файлы по версии&raquo; в меню выбора режима сортировки. К сожалению, простой правкой конфига тут обойтись не получилось, поэтому пришлось пересобрать пакет mc целиком — еще 40 минут, но оно того стоило :-)</p>
<hr />Мегаполезной фичей вдруг оказалось пользовательское меню, которым я раньше почти никогда не пользовался (наверно, потому, что там ничего полезного не было — ну на кой мне &laquo;распаковать архив&raquo;, если я то же самое сделаю тремя привычными способами). Прочитав раздел справки про mc.menu и добавив в ~/.mc/menu несколько строчек, я сэкономил себе кучу времени, тратившегося на бесконечные  </p>
<pre>vimdiff Alt-A Alt-Enter Tab Alt-A Alt-Enter Enter</pre>
<p>и </p>
<pre>diff -rubB Alt-A  Tab Alt-A Enter</pre>
<p>Этот код добавляет в меню две команды: сравнения двух каталогов и мержа файла в одном каталоге с одноименным файлом в другом каталоге:</p>
<pre>d   Compare directories
    if [ "%d" = "%D" ]; then
      whiptail --msgbox "The two directores must be different" 7 60
      exit 1
    fi
    diff -rubB "%d" "%D" | vim -

# обычный непомеченный файл
+ t r &#038; ! t t
f   Diff &#038; merge file under cursor with the same file in other panel
    if [ "%d" = "%D" ]; then
        # если в противоположной панели открыта та же папка
        whiptail --msgbox "The two directores must be different" 7 60
      exit 1
    fi
    if [ ! -f "%D/%f" ] ; then
       # если в противоположной панели нет файла с таким же именем
        whiptail --msgbox "No copy of %f in %D" 7 60
        exit 1
    fi
    if diff -q "%D/%f" "%d/%f" ; then
       # если файлы не различаются
        whiptail --msgbox "%D/%f and %d/%f are identical" 10 80
        exit 1
    fi
    vimdiff "%d/%s" "%D"</pre>
]]></description>
		<wfw:commentRss>http://bappoy.pp.ru/2009/06/18/mc-tricks.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

