<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.linuxformat.ru/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki.linuxformat.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Human</id>
		<title>Linuxformat - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.linuxformat.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Human"/>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:Contributions/Human"/>
		<updated>2026-05-13T15:16:40Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.19.20+dfsg-0+deb7u3</generator>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Apache-4.png</id>
		<title>Файл:LXF90-Apache-4.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Apache-4.png"/>
				<updated>2008-03-26T15:37:58Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Apache-3.png</id>
		<title>Файл:LXF90-Apache-3.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Apache-3.png"/>
				<updated>2008-03-26T15:37:50Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Apache-2.png</id>
		<title>Файл:LXF90-Apache-2.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Apache-2.png"/>
				<updated>2008-03-26T15:37:36Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF-Apache-1.png</id>
		<title>Файл:LXF-Apache-1.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF-Apache-1.png"/>
				<updated>2008-03-26T15:37:18Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/LXF90:Apache</id>
		<title>LXF90:Apache</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/LXF90:Apache"/>
				<updated>2008-03-26T15:22:08Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Новая: == Перышки вам в шляпу == ''Решили научить свой сервер Apache новым трюкам? Узнайте у '''Пола Хадсона''' про тр...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Перышки вам в шляпу ==&lt;br /&gt;
''Решили научить свой сервер Apache новым трюкам? Узнайте у '''Пола Хадсона''' про три его любимых модуля Apache для web-суперобслуживания.''&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF-Apache-1.png|thumb|«Моя маман говаривала, что Synaptic похож на коробку шоколада» – модули с какой начинкой вы предпочтете?]]&lt;br /&gt;
'''Приспособить Apache для обслуживания web-страниц может каждый, а при известной сноровке можно установить и использовать mod_php или mod_perl, но Apache способен на большее. Стандартная установка Ubuntu Edgy (с подключенными репозиториями Universe и Multiverse) дает перечень свыше сорока модулей Apache 2, с которыми ваш сервер Apache натворит такого, чего вы и представить не могли.'''&lt;br /&gt;
&lt;br /&gt;
На этих четырех страницах мы расскажем вам про три наших любимых модуля ''Apache'' и научим работать с каждым из них. О некоторых из их функций вы, может, и слышали, но никогда не пробовали – а может, и вообще о них не знали – но запустите их в работу, и закачки пойдут быстро как никогда!&lt;br /&gt;
&lt;br /&gt;
== mod_userdir: Домашние страницы – народу! ==&lt;br /&gt;
&lt;br /&gt;
Дистрибутивы, основанные на Debian, стандартно используют виртуальный хостинг, он превосходен для настройки большого числа сайтов на коммерческой основе. А если вы просто хотите выделить своим друзьям местечко на вашем сервере? Лучший способ сделать это – модуль '''mod_userdir''', дающий каждому пользователю с учетной записью на вашем сервере возможность размещать свой собственный контент.&lt;br /&gt;
&lt;br /&gt;
Откройте файл конфигурации '''/etc/Apache2/sites-available/default''' в текстовом редакторе (как суперпользователь) и добавьте такую строку:&lt;br /&gt;
&lt;br /&gt;
 UserDir public_html&lt;br /&gt;
&lt;br /&gt;
Пользователи теперь смогут создавать подкаталог '''public_html''' в своем домашнем каталоге и получать к нему доступ по адресу http://www.yoursite.com/~username. У кого не будет каталога '''public_html''', тот не будет представлен в Интернете – при попытке зайти на его страничку возникнет ошибка 404.&lt;br /&gt;
&lt;br /&gt;
Для определения полного пути, например, '''/var/www''', можно использовать директиву UserDir: в этом случае http://www.yoursite.com/~hudzilla будет искать страницы в '''/var/www/hudzilla'''. Но в принципе, лучше оставить ее в домашнем каталоге пользователя, так как это упрощает настройку прав доступа – пользователи смогут создавать и удалять свой собственный контент в '''public_html''' без вашего содействия. Вы можете также использовать директиву '''UserDir''', чтобы разрешать или запрещать работу модуля '''mod_userdir''' пользователям индивидуально. Например, сейчас каждый может публиковать пользовательские данные в личном web-пространстве, даже root – зайдите на http://www.yousite.com/~root, и поймете, что мы имеем в виду.&lt;br /&gt;
&lt;br /&gt;
Как правило, разумнее пресечь подобный доступ, так что добавьте в конфигурацию такую строку:&lt;br /&gt;
&lt;br /&gt;
 UserDir disabled root&lt;br /&gt;
&lt;br /&gt;
Здесь можно указать столько пользователей, сколько хотите. Вариант – настроить «белый список» '''mod_userdir''', запретив доступ всем и разрешив только тем, кому нужно:&lt;br /&gt;
&lt;br /&gt;
 UserDir disabled&lt;br /&gt;
 UserDir enabled bill ted&lt;br /&gt;
&lt;br /&gt;
== mod_cband: квоты для виртуальных серверов ==&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Apache-2.png|thumb|На странице статуса mod_cband дана детальная информация по всем квотам и ограничениям, но уж больно крошечным шрифтом!]]&lt;br /&gt;
Некоторые модули ''Apache'' могут ограничивать использование канала во времени; некоторые – ограничивать число запросов, обслуживаемое доменом в секунду; а некоторые накладывают постоянное ограничение на исходящий трафик вашего сервера. Второй из нашего трио модулей, '''mod_cband''', делает все это и даже больше – что сокращает время обучения, упрощает долгосрочное администрирование и снижает требования к ресурсам вашего сервера.&lt;br /&gt;
&lt;br /&gt;
Для тестирования модуля создайте текстовый файл побольше, этак на 16 МБ, набитый абракадаброй, в каталоге '''/var/www'''. Простейший способ это сделать – ввести команду&lt;br /&gt;
&lt;br /&gt;
 sudo dd if=/dev/urandom of=/var/www/myfile bs=16M count=1&lt;br /&gt;
&lt;br /&gt;
Прежде чем применять ограничения, скоренько проверим, читается ли этот файл. Запустите '''wget http://localhost/myfile''', и он должен загрузиться в текущий каталог. Обратите внимание на скорость, которой достигнет ''wget'' – наша составила 44,15 Мбит/сек, для локального файла нормально.&lt;br /&gt;
&lt;br /&gt;
Откройте '''/etc/Apache2/sites-available/default''' как root в любимом текстовом редакторе и взгляните на директиву '''DocumentRoot'''. Она будет установлена в '''/var/www''' – нам того и надо, только добавим еще две строки прямо под ней:&lt;br /&gt;
&lt;br /&gt;
 ServerName localhost&lt;br /&gt;
 CBandSpeed 1024 5 30&lt;br /&gt;
&lt;br /&gt;
Именно в строке '''CBandSpeed''' и происходит самое интересное: она ограничивает наш сервер до 1024 Кбит/сек, при максимуме в 5 запросов в секунду и 30 одновременно открытых соединений. Если вы теперь запустите ''wget'' (файл конфигурации не закрывайте – он скоро вам снова понадобится), то увидите изрядное снижение скорости, поскольку '''mod_cband''' автоматически «душит» канал.&lt;br /&gt;
&lt;br /&gt;
=== Ограничение использования за период ===&lt;br /&gt;
&lt;br /&gt;
{{Врезка|right|Ширина=300px&lt;br /&gt;
|Заголовок=Как установить модуль&lt;br /&gt;
|Содержание=Каждый из рассматриваемых здесь модулей доступен через ''Synaptic'', если подключены репозитории Universe и Multiverse. Процесс активации установленных модулей полностью выполняется из командной строки: получите права root, перейдите в '''/etc/apache2''' и выполните эту команду:&lt;br /&gt;
&lt;br /&gt;
 ln -s mods-available/somemod.so mods-enabled/&lt;br /&gt;
&lt;br /&gt;
Создастся символьная ссылка на активируемый модуль, так что для его запрета просто удалите файл-ссылку из '''mods-enabled'''. Активировав все модули, какие вы хотели, выполните команду '''apache2ctl restart''', чтобы Apache перезапустился и изменения вступили в силу. Перезапускать Apache нужно при каждом изменении конфигурации согласно этому описанию.}}&lt;br /&gt;
Модуль '''mod_cband''' вполне способен распределять ограничение ширины канала сайта во времени. Находясь в '''/var/www''', запустите для начала следующие две команды:&lt;br /&gt;
&lt;br /&gt;
 sudo mkdir scoreboard&lt;br /&gt;
 sudo chown www-data scoreboard&lt;br /&gt;
&lt;br /&gt;
'''mod_cband''' будет хранить информацию о суммарном трафике, использованном каждым сайтом, в каталоге '''scoreboard''', так что он должен быть доступен на запись пользователю, с правами которого работает ''Apache'' ('''www-data'''). Вернувшись в файл конфигурации, добавьте следующие четыре строки:&lt;br /&gt;
&lt;br /&gt;
 CBandLimit 40M&lt;br /&gt;
 CBandScoreboard /var/www/scoreboard&lt;br /&gt;
 CBandExceededURL http://www.linuxformat.co.uk&lt;br /&gt;
 CBandPeriod 1M&lt;br /&gt;
&lt;br /&gt;
Если вы точно следовали нашим инструкциям, то обнаружите, что при запуске команды ''wget'' никакой разницы не наблюдается. Фактически, вы можете запустить ее трижды и ничего не увидеть. Что же изменилось? А магия-то начинается с четвертой попытки: вы обнаружите, что ''wget'' не скачает файл '''myfile''' по новой, а перейдет на http://www.linuxformat.co.uk. Наш файл имеет размер 16 МБ, а директива '''CBandLimit''' настроена на запрет доступа после достижения предела в 40 МБ. Так что первое скачивание работает, поскольку уже скачано 0 МБ, второе работает, поскольку скачано 16 МБ (размер первой закачки), третье скачивание тоже работает, потому что скачано 32 МБ (сумма двух первых закачек), а вот четвертая и последующая закачки завершатся неудачей, поскольку к тому времени будет скачано уже 48 МБ, что на 8 МБ превышает лимит для вашего сайта.&lt;br /&gt;
&lt;br /&gt;
Тут в дело вступает директива '''CBandExceededURL''': как только будет достигнут предел трафика, любые запросы, поступающие в наш домен, автоматически перенаправятся на http://www.linuxformat.co.uk. Примечание: если вы попробуете это дома, то, мы уверены, осчастливите Майка, администратора сайта Команды LXF, увеличив посещаемость его детища! Хотя вы, видимо, захотите сослаться на какую-нибудь другую страницу, разъясняющую, что был превышен лимит трафика, и как можно докупить еще.&lt;br /&gt;
&lt;br /&gt;
Наконец, директива '''CBandPeriod''' – это суммарное время между сбросами счетчиков трафика. Мы указали '''1M''', то есть каждую минуту счетчик использования трафика нашего локального сайта будет сбрасываться на ноль, и пользователи смогут скачать следующие 40 МБ контента. Да, '''mod_cband''' использует M и для мегабайтов, и для минут, но это единственная реальная накладка. Для скоростей закачки можно также использовать K и G (если у вас действительно быстрый интернетканал!), а для периодов времени можно использовать S (секунды), H (часы), D (дни), и W (недели).&lt;br /&gt;
&lt;br /&gt;
Есть две альтернативы директиве '''CBandExceededURL'''. Одна – полностью удалить эту строку, тогда '''mod_cband''' будет выдавать сообщение об ошибке HTTP 503 «Сервис временно недоступен». А можно применить директиву '''CBandExceededSpeed''', она переопределяет '''CBandSpeed''' в случае превышения лимита трафика. Например, вы хотите, чтобы сайт поддерживал 1024 Кбит/сек, пока не будет достигнут порог в 5 ГБ, а затем – лишь 128 Кбит/сек до конца месяца. Вот как это можно сделать:&lt;br /&gt;
&lt;br /&gt;
 CBandSpeed 1024 5 30&lt;br /&gt;
 CBandLimit 5G&lt;br /&gt;
 CBandScoreboard /var/www/scoreboard&lt;br /&gt;
 CBandExceededSpeed 128 5 30&lt;br /&gt;
 CBandPeriod 4W&lt;br /&gt;
&lt;br /&gt;
Одновременно использовать '''CBandExceededSpeed''' и '''CBandExceededURL''' нет смысла, поскольку они взаимоисключающие: вы либо обслуживаете страницу с ограниченной скоростью, либо перенаправляете запрос.&lt;br /&gt;
&lt;br /&gt;
=== Отчеты о состоянии ===&lt;br /&gt;
&lt;br /&gt;
Можете проверять состояние '''mod_cband''' в любое время, используя особое место на вашем сайте. Допустим, вы хотите разрешить пользователям просматривать свои лимиты и узнавать, сколько уже выбрано. Отредактируйте файл конфигурации таким образом:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;Location /bandwidth-status&amp;gt;&lt;br /&gt;
   SetHandler cband-status-me&lt;br /&gt;
  &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете теперь зайти на http://localhost/bandwidth-status, да и любой тоже может – советуем установить пароль на каталог, чтобы сюда попадали только свои люди.&lt;br /&gt;
&lt;br /&gt;
Администраторам в масштабе сервера (то есть вам), наверно, захочется видеть глобальное использование трафика, а также информацию о состоянии всех размещенных доменов. Для этого добавьте в свой файл конфигурации следующие строки для своего домена (но не для ваших клиентов):&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;Location /bandwidth-status&amp;gt;&lt;br /&gt;
    SetHandler cband-status&lt;br /&gt;
 &amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== mod_rewrite: Перезапись URL динамически ==&lt;br /&gt;
&lt;br /&gt;
{{Врезка|right|Ширина=300px&lt;br /&gt;
|Заголовок=Почему mod_access есть зло?&lt;br /&gt;
|Содержание=Временно разрешать '''mod_access''', работая с '''mod_rewrite''', вполне нормально, поскольку это значительно снижает суммарное время отладки ваших регулярных выражений. Но закончив, сразу же запретите переопределение настроек, чтобы '''mod_access''' был капитально пресечен. Дело это хорошее, потому что '''mod_access''' спроектирован для поиска опций, которые следует установить в ваших каталогах, в файлах '''.htaccess'''. На вид безвредно, но представьте: если ваш каталог '''/foo''' требует пароль, как ''Apache'' догадается, что нужно спросить пароль, когда пользователь полезет в '''/foo/bar/baz.php'''?&lt;br /&gt;
&lt;br /&gt;
Ответ заключается в том, что ''Apache'' просматривает .htaccess-файлы в запрошенном каталоге, а также во всех родительских каталогах, вплоть до корня вашей файловой системы. Так, в приведенном выше примере ''Apache'' ищет (и читает, если найдет) следующие файлы:&lt;br /&gt;
* /var/www/foo/bar/.htaccess&lt;br /&gt;
* /var/www/foo/.htaccess&lt;br /&gt;
* /var/www/.htaccess&lt;br /&gt;
* /var/.htaccess&lt;br /&gt;
* /.htaccess&lt;br /&gt;
...на что уходит уйма времени. Отключите это и используйте ваш процессор в полезных целях!}}&lt;br /&gt;
Всякий мастер-класс ''Linux Format'' был бы неполон без разборки регулярных выражений, и данный – не исключение. Модуль ''Apache'' '''mod_rewrite''' придуман для проверки на соответствие строк запросов и их изменения на лету. Очень популярно использовать '''mod_rewrite''' для сокращения длинных URL, чтобы их легче было запоминать и набирать. Например, если вы хотите, чтобы www.example.com/shortcut молча перенаправлялся на www.example.com/foo/bar/baz/wombat, воспользуйтесь '''mod_rewrite'''.&lt;br /&gt;
&lt;br /&gt;
Тут вы, верно, подивитесь: а чем отличается '''mod_rewrite''' от отсылки HTTP-заголовка Location для перенаправления браузера? Действительно, разница невелика: оба переключают один URL на другой. Однако '''mod_rewrite''' в общем удобнее для пользователя, поскольку заголовок Location говорит браузеру прекратить загрузку текущей страницы и вместо этого загрузить другой URL, а '''mod_rewrite''' ничего клиенту не сообщает, просто молча переписывает URL, чтобы тот указывал на другое место – пользователь и не заметит, что произошло.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Apache-3.png|thumb|Работая с '''mod_rewrite''', знайте, что «Internal Server Error» на языке Apache значит «напортачил ты в регулярном выражении, балда!»]]&lt;br /&gt;
Иначе говоря, '''mod_rewrite''' делает то же, что и Location, только прозрачно для конечного пользователя. Единственная издержка использования '''mod_rewrite''' – процессорное время, потому что Apache проверяет каждый входящий запрос на соответствие имеющемуся списку правил перезаписи, но это влияние довольно незначительно.&lt;br /&gt;
&lt;br /&gt;
Итак, возвращаясь к примеру, где www.example.com/shortcut должен молча превратиться в www.example.com/foo/bar/baz/wombat – вот как это можно сделать с помощью '''mod_rewrite''':&lt;br /&gt;
&lt;br /&gt;
 RewriteEngine On&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;RewiteRule shortcut/([A-Za-z0-9]*) /foo/bar/baz/wobmat/$1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Правило '''mod_rewrite''' имеет пять важных моментов:&lt;br /&gt;
* Запрос на www.yoursite.com/shortcut покажет содержимое каталога www.yoursite.com/foo/bar/baz/wombat.&lt;br /&gt;
* Запрос на www.yoursite.com/shortcut/hello отобразит файл www.yoursite.com/foo/bar/baz/wombat/hello.&lt;br /&gt;
* Фрагмент '''$1''' ссылается на группу регулярного выражения (часть, заключенная в скобки) и использует ее в перезаписываемом URL.&lt;br /&gt;
* Пользователь и не заподозрит, что просматривает '''/foo/bar/baz/wombat''', а не '''/shortcut''' – ''Apache'' все делает тишком.&lt;br /&gt;
* Каталог '''/foo/bar/baz/wombat''' по-прежнему доступен напрямую.&lt;br /&gt;
Теперь вы видите, чем хороша прозрачность: все, что соответствует URL www.yoursite.com/shortcut, будет автоматически перезаписано. Немного изменив правило (предусмотрев символы /, ., = и &amp;amp;), вы даже сможете перезаписывать целые URL, преобразуя www.yoursite.com/shortcut/gubbins/foo.php?bar=baz в www.yoursite.com/foo/bar/baz/wombat/gubbins/foo.php?bar=baz.&lt;br /&gt;
&lt;br /&gt;
=== Перезапись – углубленно ===&lt;br /&gt;
&lt;br /&gt;
{{Врезка|right|Ширина=300px&lt;br /&gt;
|Заголовок=Идем дальше&lt;br /&gt;
|Содержание=Если вы проработали каждый из этих модулей, вот еще три рекомендации на пробу:&lt;br /&gt;
* '''mod_dnssd''' Публикует ваш сайт, используя протокол обнаружения сети Apple Bonjour.&lt;br /&gt;
* '''mod_musicindex''' Позволяет всему миру листать вашу музыкальную коллекцию, а также и прослушивать ее.&lt;br /&gt;
* '''mod_mono''' Apache встречается с Mono... Разместите C# на своем сервере и запускайте ASP.NET через Apache.&lt;br /&gt;
Итак, какой модуль Apache ваш любимый? У вас есть трюк с '''mod_rewrite''', который вам особо по душе? Напишите нам, а лучший мы опубликуем! letters@linuxformat.ru.}}&lt;br /&gt;
Не будем заострять внимание, но ваши правила перезаписи вряд ли заработают с первого раза. Обычно требуется не одна попытка, и вы, скорее всего, добьетесь их правильности, лишь вволю наскрежетавшись зубами. Так что, добавляя новые правила, вы можете предпочесть положиться (временно!) на файлы .htaccess: они временно изменяют установки конфигурации ''Apache'' для конкретного каталога. Чтобы разрешить использование файлов .htaccess, загляните в конфигурацию ''Apache'' (ту, что мы уже используем), и для каталога '''/var/www''' измените  ‘AllowOverride None’ на ‘AllowOverride All’. Перезапустите ''Apache'', и файлы .htaccess готовы к работе!&lt;br /&gt;
&lt;br /&gt;
Пора попробовать что-нибудь поинтереснее. Да, укорочение длинного URL – типовое применение '''mod_rewrite''', но еще популярнее приведение уродских URL к виду, простому для запоминания. Например, www.yoursite.com/index.php?Section=Bugs&amp;amp;User=Hudzilla – URL ужасный, а www.yoursite.com/users/hudzilla/bugs и запомнить легче, и для глаза приятнее! '''mod_rewrite''' поможет горю, например, таким образом:&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;RewriteRule ^users/([A-Za-z0-9_])+/bugs$ index.php?Section=bugs&amp;amp;User=$1&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Символы '''^''' и '''$''' означают «начало строки запроса» и «конец строки запроса» соответственно, они избавят ''Apache'' от обработки чего-то типа www.yoursite.com/users/hudzilla/bugs/monkeybutts.&lt;br /&gt;
&lt;br /&gt;
Использование точных правил очень полезно, когда нужно проверять соответствие множества различных вещей. Например, вам может потребоваться загружать страницу поиска пользователя, когда на www.yoursite.com/users зайдет посетитель, а значит, строка '''RewriteRule''' должна явно игнорировать все, что добавляет имя пользователя в конец запроса. Можете написать столько строк '''RewriteRule''', сколько потребуется, но помните, что ''Apache'' прогоняет каждый запрос через каждую из строк '''RewriteRule''', и неаккуратные правила потребуют довольно интенсивной работы процессора!&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Apache-4.png|thumb|Использование файлов .htaccess для свежесоставленных правил mod_rewrite позволит&lt;br /&gt;
не перезапускать Apache при каждом мелком изменении.]]Опытные пользователи могут добавить себе через условия '''mod_rewrite''' большей мощности. Например, если ваш сайт размещает множество изображений, и вы не хотите, чтобы другие сайты высасывали ваш трафик, устанавливая ссылки непосредственно на ваш сервер, вы можете использовать что-нибудь наподобие&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  RewriteEngine on&lt;br /&gt;
  RewriteCond %{HTTP_REFERER} !^$&lt;br /&gt;
  RewriteCond %{HTTP_REFERER} !^http://www.yoursite.com/.*$&lt;br /&gt;
  RewriteRule \.(jpg|png)$ - [F]&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
Здесь три важных строки. Первая проверяет, не равен ли referrer значению '''^$''' – т.е. пустой строке. Учтите, что «referrer» пишется здесь с одной ‘r’ ('''HTTP_REFERER''') из-за исторической опечатки. Если первая проверка проходит, то выполняется вторая: не совпадает ли referrer с именем нашего сайта? Это вторая строка кода. Символы .* в конце означают «соответствует всему», так что будет совпадение с любым URL, размещенным на нашем сайте. Наконец, если обе строки '''RewriteCond''' выполняются, срабатывает строка '''RewriteRule'''. Она отбирает JPEG- и PNG-файлы и перезаписывает их в – '''&amp;lt;nowiki&amp;gt;[F]&amp;lt;/nowiki&amp;gt;''', так в '''mod_rewrite''' сокращенно обозначено нечто невежливое вроде «запрещено – вали отсюда!».&lt;br /&gt;
&lt;br /&gt;
Мы могли бы усовершенствовать второе rewrite-условие, добавив '''&amp;lt;nowiki&amp;gt;[NC]&amp;lt;/nowiki&amp;gt;''' в конец этой строки, что велит ''Apache'' игнорировать регистр символов в запросе, рассматривая www.YOURSITE.com и www.yoursite.com как один и тот же путь.&lt;br /&gt;
&lt;br /&gt;
Если вы озверели от безуспешной борьбы с '''mod_rewrite''', можете либо расслабиться, глубоко вдохнуть и попробовать снова, либо поступить как все: взреветь от ярости и пнуть свой компьютер через всю комнату. Но что бы вы ни сделали, утешайтесь фактом, что проблемы бывают даже у профи. Брайан Белендорф [Brian Behlendorf], основатель ''Apache'' Software Foundation, как-то сказал: «'''mod_rewrite''' замечателен тем, что дает вам всю настраиваемость и гибкость Sendmail. Оборотная сторона медали – он дает вам всю настраиваемость и гибкость Sendmail.» Будьте упорны, и все получится!&lt;br /&gt;
&lt;br /&gt;
Учтите: как только вы закончите с '''mod_rewrite''', советуем изменить ‘AllowOverride All’ обратно на ‘AllowOverride None’: '''mod_access''' (модуль, который работает с файлами .htaccess) – это гарантированное узкое место производительности. [http://www.linuxformat.ru LXF]&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/LXF90:%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6</id>
		<title>LXF90:Спецрепортаж</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/LXF90:%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6"/>
				<updated>2008-03-23T22:03:19Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Новая: == Проблемы Linux решены == ''Что, завязли? Руководство '''Грэма Моррисона''' по типичным проблемам в Linux долж...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Проблемы Linux решены ==&lt;br /&gt;
''Что, завязли? Руководство '''Грэма Моррисона''' по типичным проблемам в Linux должно стронуть вас с места.''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
'''Нечего стыдиться, если вы застряли на простой с виду проблеме в Linux. Знайте: множество вопросов по Linux люди задают снова и снова – и не потому, что ленятся искать ответы самостоятельно, а потому, что очень часто на это нет времени или данное проявление проблемы не похоже на обычное. Почему видеодрайверы так трудно устанавливать? Что случилось с моим интернет-соединением? Почему не устанавливается эта программа?'''&lt;br /&gt;
&lt;br /&gt;
Linux не является причиной проблем. В наши дни можно твердо сказать, что с Linux проблем не больше, чем с любой другой операционной системой, и подавляющее их большинство – это результат почти бесконечных комбинаций оборудования, которые можно встретить на типичных ПК. Обычный источник проблем – плохо поддерживаемое оборудование или то, что пользователь не знаком с ОС. Для большинства пользователей установка диска с последней версией Ubuntu в CD- или DVD-привод окончится без неприятностей. Но некоторые общие проблемы время от времени выплывают наружу – будь то «железо» или ПО, установка или администрирование. И из-за многовариантной природы Linux и оборудования, на котором он работает, бывает трудно точно указать причину.&lt;br /&gt;
&lt;br /&gt;
На последующих страницах – кроме подробных ответов по типовым проблемам – мы еще и попытаемся научить вас решать такие проблемы. Ключ к решению – понимание взаимодействия ОС и оборудования, а также работы различных компонентов вашего дистрибутива Linux. Глубокое знание Linux само по себе награда, но оно также помогает разобраться с неприятными инцидентами.&lt;br /&gt;
&lt;br /&gt;
Мы должны предупредить вас, что – хотя это и очевидно – некоторые внесенные изменения могут иметь катастрофические последствия для вашей Linux-системы, если они сделаны неправильно. Поэтому обязательно обезопасьте все ваши данные: вдруг что-то пойдет наперекосяк. Нам всем случалось раскаиваться, что мы отложили резервное копирование на потом; итак, вашим первым заданием, еще до чтения, будет создание резервной копии!&lt;br /&gt;
&lt;br /&gt;
== Установка ==&lt;br /&gt;
''Что делать, если все отказало еще до того, как дистрибутив оказался на вашем жестком диске.''&lt;br /&gt;
&lt;br /&gt;
'''У некоторых невезучих Linux даже не устанавливается. Вы-то думали, что инсталляция – самый отлаженный аспект дистрибутивов Linux, поскольку и разработчики, и пользователи должны пройти одни и те же этапы; но это, к сожалению, неверно.'''&lt;br /&gt;
&lt;br /&gt;
Последние релизы, как Fedora Core, так и Ubuntu, намучились с процедурами установки, и хотя большинство пользователей запускает Linux без сучка без задоринки, итогом этого процесса может стать пустой экран и голый диск. Причины проблем весьма различны, но большинство из них сводится к оборудованию. Ваши шансы на успех сильно возрастут, если еще до инсталляции дистрибутива вы постараетесь сделать свою машину как можно более стандартной.&lt;br /&gt;
&lt;br /&gt;
Это означает удаление всех ненужных для инсталляции устройств. Может помочь попытка использовать IDE-диск вместо более современного SATA-варианта, а также отключение ненужных карт расширения и USB-периферии. Linux отлично адаптируется, и устройства легко будет добавить после завершения процесса первоначальной установки.&lt;br /&gt;
&lt;br /&gt;
Следует также убедиться, что вы используете последнюю версию BIOS для вашей материнской платы (ее можно скачать с сайта изготовителя вашей «материнки»). Номер версии BIOS мелькает на экране при включении компьютера. Его также можно проверить в меню BIOS, нажав [F2] или [F12] во время загрузки.&lt;br /&gt;
&lt;br /&gt;
=== Прощай, ACPI! ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Спецрепортаж-13.png|thumb|Загрузчик Grub появляется при запуске Linux-дистрибутива. Можно отредактировать пункты меню и добавить более совместимые с вашим «железом» опции: для входа в режим редактирования нажмите &amp;lt;Escape&amp;gt;, а затем &amp;lt;e&amp;gt;.]]Если проблем избежать не удалось, существует довольно большой шанс заставить вашу систему работать, отключив ACPI. Это функция управления питанием, встроенная в каждый современный BIOS/материнскую плату, но ее реализация далека от стандарта и может вызывать проблемы. Если вы хотите попробовать отключить ACPI, сделайте это из меню загрузки до того, как что-нибудь загрузится. Во-первых, большинство современных дистрибутивов Linux используют сис-&lt;br /&gt;
тему загрузочного меню, именуемую ''Grub''. Установлен ли ''Grub'', можно узнать по появлению сообщения «Grub loading, please wait» после инициализации BIOS. Если вы такого не увидите, ваш дистрибутив, вероятно, использует старую альтернативу, именуемую ''Lilo'' – попробуйте более новый дистрибутив.&lt;br /&gt;
&lt;br /&gt;
Увидев сообщение «Grub», нажмите клавишу {{oncolor||green|Escape}}. Откроется меню опций для загрузки вашей системы. Нужно выделить опцию загрузки по умолчанию (обычно вверху списка) и нажать клавишу {{oncolor||green|e}}. Далее, выделите строку, начинающуюся со слова «kernel», и снова нажмите {{oncolor||green|e}}. Это редактирование строки конфигурации ядра для меню ''Grub'': нужно добавить «acpi=off», нажать {{oncolor||green|Enter}}, а затем {{oncolor||green|b}} для загрузки вашего модифицированного пункта. Если это решит вашу проблему, можете сделать данное изменение постоянным, добавив «acpi=off» в той же строке ядра в '''/boot/grub/menu.lst''' в вашей установленной Linux-системе. Чтобы сохранить изменения на диске, вам нужно будет отредактировать этот файл с правами администратора системы.&lt;br /&gt;
&lt;br /&gt;
=== Ошибки памяти ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Спецрепортаж-14.png|thumb|Если память выдюжила испытание огнем Memtest86, значит, проблемы не здесь]]Ошибку вызывать может также какой-либо аппаратный компонент. Linux предъявляет к оборудованию гораздо больше требований, чем другие ОС, и поэтому первоначальная установка Linux может первой выявить признаки сбоя. Обычно главный виновник – память, т.к. при превосходном функционировании всего модуля сбои может давать одна небольшая секция. Linux старается использовать столько памяти, сколько может потребоваться для оптимизации дискового кэша или временного файла, и прихватывает ту память, которой другие операционные системы касаться не рискуют. Ошибки памяти могут возникать случайным образом и приводить к зависанию вашей машины, повреждению изображения на экране или возникновению различных случайных системных ошибок.&lt;br /&gt;
&lt;br /&gt;
Вы можете выяснить, в памяти ли дело, запустив программу под названием ''Memtest86''. Она существует уже довольно долго (она унаследована от ранней версии ядра Linux). Ее нужно загружать прямо с CD/DVD-ROM или дискеты (еще помните такие?); загрузившись, она запустит исчерпывающую серию тестов вашей памяти. Если ваша память переживет эту пытку, не выдав никаких ошибок, можете быть почти уверены, что проблем с нею нет. Если ''Memtest'' что-нибудь обнаружит, придется заменить неисправный модуль (купите, одолжите или стяните другой). Стоит это примерно 2-3 тыс. рублей за 1 ГБ-модуль, но вы обнаружите, что такая замена сделает более стабильными и другие ОС на этой машине.&lt;br /&gt;
{{Врезка&lt;br /&gt;
|Заголовок='''Шаг за шагом: Создаем home-раздел'''&lt;br /&gt;
|Содержание=Одной из наиболее полезных корректив при установке Linux-системы является создание отдельного дискового раздела для домашних каталогов. Не жалейте затраченного времени: это упростит и обновление дистрибутива, и создание резервных копий ваших данных. Системные файлы храните в корневом разделе, а пользовательские данные – в home-разделе. Во время обновления убедитесь, что инсталлятор переформатирует только корневой раздел, а home-раздел не трогает.&lt;br /&gt;
{{{!}}&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-1.png|thumb|center]]&lt;br /&gt;
* '''Ручное редактирование'''&lt;br /&gt;
В этом примере мы воспользовались Ubuntu, но в большинстве дистрибутивов процесс похожий. Первый шаг – позаботиться о ручном изменении таблицы разделов, не позволив инсталлятору полностью управлять выделением дискового пространства.&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-2.png|thumb|center]]&lt;br /&gt;
* '''Выделение памяти'''&lt;br /&gt;
Как минимум, не считая Windows-раздела, вам потребуются разделы ‘root’, ‘home’ и ‘swap’. Последний может быть небольшим (два объема ОЗУ), а размер остальных двух зависит от того, где вы собираетесь хранить свои данные.&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-3.png|thumb|center]]&lt;br /&gt;
* '''Выбор места'''&lt;br /&gt;
Наконец, укажите подходящую точку монтирования (место в вашей файловой системе) для каждого раздела: / для корневого раздела, /home для домашних каталогов и swap для оставшегося раздела.&lt;br /&gt;
{{!}}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Оборудование ==&lt;br /&gt;
''Заставить оборудование работать – не обязательно сложная задача.''&lt;br /&gt;
&lt;br /&gt;
{{Врезка|right|Ширина=400px&lt;br /&gt;
|Заголовок=«Скорая помощь» по оборудованию&lt;br /&gt;
|Содержание=&lt;br /&gt;
* Введите '''lspci''' в окне терминала, чтобы увидеть список всех устройств, подключенных к вашей системе. Как правило, вы увидите больше информации, чем могли бы ожидать, потому что современные материнские платы зачастую объединяют несколько устройств в одно. Если ваше оборудование здесь не появилось, возможно, оно плохо подсоединено.&lt;br /&gt;
* Есть несколько способов растянуть ваш рабочий стол на два экрана. Стандартный метод – использование ''Xinerama'' и дублирование различных секций в '''xorg.conf''', но в случае с оборудованием от Nvidia можно также воспользоваться инструментом от изготовителя и активировать режим «TwinView».&lt;br /&gt;
* Если вы хотите использовать с Linux MP3-плейер, выбирайте такой, который монтируется как внешний накопитель. Вы сможете скопировать на него свои музыкальные файлы как на USB-диск и управлять своей коллекцией при помощи обычного файлового менеджера.&lt;br /&gt;
* При сборке собственных приложений и драйверов в Ubuntu нужно установить базовое окружение для сборки, введя в командной строке следующее:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install build-essential linux-headers-`uname -r`&lt;br /&gt;
* Когда вы собираете собственный модуль драйвера или устанавливаете проприетарный модуль от поставщика оборудования, вы сможете гарантировать его подгрузку во время старта системы, добавив имя модуля в файл '''/etc/modules'''.}}&lt;br /&gt;
&lt;br /&gt;
'''Заставить определенные «железки» работать в Linux пока что проблема. На это есть две принципиальных причины. Во-первых, возможных комбинаций оборудования бывает множество. Типичная ситуация – когда материнская плата от одного изготовителя, видеокарта – от другого, а внешняя периферия, например, принтер, мышь и клавиатура – от толпы каких-то других сборщиков. И каждому подавай свой драйвер, а драйверы часто еще и взаимодействуют друг с другом. Понятно, что изготовитель не в силах протестировать все возможные комбинации драйверов.'''&lt;br /&gt;
&lt;br /&gt;
Это сочетается со второй причиной: многие изготовители пока отказываются открыть спецификации своего оборудования, чтобы разработчики могли писать драйверы. Linux уже может похвастать превосходной поддержкой оборудования от Intel, IBM и AMD, но по-прежнему очень важно убедиться в совместимости нового оборудования, прежде чем выкладывать за него денежки. Следует также проверить наличие открытого драйвера для вашего оборудования, поскольку сообщество мало чем поможет, если драйвер закрыт. Чтобы разобраться в этих вещах, загляните на http://cdb.suse.de, http://www.mandriva.com/hardware или http://www.phoronix.com/lch.&lt;br /&gt;
&lt;br /&gt;
=== Проблемные видеокарты ===&lt;br /&gt;
&lt;br /&gt;
Типовая «горячая тема» для оборудования в Linux – заставить работать видеокарту с 3D-ускорителем. По умолчанию большинство Linux-дистрибутивов устанавливают для оборудования открытый драйвер. Последняя версия Ubuntu может прервать эту тенденцию, включив проприетарные драйверы, но покамест вы получаете видео-драйверы с открытым кодом, обеспечивающие лишь минимальную поддержку 3D-ускорения. Этого достаточно для обычного использования настольного ПК, но если вы захотите поиграть в ''PlanetPenguin Racer'' или создать сцену в ''Blender'', ваша видеокарта не справится с нагрузкой.&lt;br /&gt;
&lt;br /&gt;
Если вы собрались купить новую 3D-видеокарту, для серьезной производительности годятся лишь два поставщика. Nvidia и ATI (ныне принадлежащая AMD) предлагают к загрузке собственные закрытые драйвера для ваших карт, и каждый использует свою процедуру установки. Альтернатива для тех, кто не гонится за модной «трехмеркой» – карты Intel; это оборудование не столь мощное, зато драйверы полностью открыты. Если карта у вас уже есть, выясните, какой чипсет в ней используется (для этого наберите в командной строке '''lspci''').&lt;br /&gt;
&lt;br /&gt;
Независимо от вашего оборудования, нужно будет установить исходные коды ядра. Каждый драйвер должен быть скомпилирован именно с той версией ядра, которую вы используете. Nvidia и ATI пытаются предоставлять прекомпилированные двоичные версии для нескольких популярных ядер и дистрибутивов, но поскольку именно ядро обычно первым заменяется при установке обновлений безопасности, нет гарантии, что эти версии за ним поспевают.&lt;br /&gt;
&lt;br /&gt;
Исходный код ядра можно установить с помощью менеджера пакетов вашего дистрибутива, выполнив поиск либо по ‘kernel-source’ (для систем Mandriva и Fedora), либо по ‘linux-source’ (для систем Ubuntu/Debian). Менеджер пакетов выяснит, какая версия вам нужна, поскольку требуется ее идеальное соответствие вашему рабочему ядру, и вы всегда можете проверить, какая версия ядра у вас запущена, набрав в командной строке '''uname -a'''. Инструкции по установки драйвера Nvidia см. в нашем пошаговом руководстве, справа.&lt;br /&gt;
&lt;br /&gt;
После установки исходных текстов ядра, следующим шагом будет запуск для нового драйвера процедуры инсталляции, предусмотренной поставщиком, то есть скачивание двоичного пакета с сайта Nvidia или ATI. Перед запуском полученного файла нужно будет закрыть текущую сессию X Window. Некоторые дистрибутивы позволяют выйти в терминал, закрыв X-сессию, но с другими вам придется закрывать сессию вручную. Сделать это можно, введя как root либо '''killall gdm''', либо '''killall kdm''', чтобы остановить процесс менеджера входа в систему.&lt;br /&gt;
&lt;br /&gt;
Более надежный способ достичь того же – переключить уровень исполнения (runlevel) с помощью команды ''init''. Различные уровни исполнения настраиваются на запуск различных процессов. Например, уровень 1 (введите '''init 1''') – обычно однопользовательская система в безопасном режиме, а уровень 5 ('''init 5''') – ваш привычный, полноценный графический рабочий стол. На беду, здесь нет единого стандарта: различные дистрибутивы используют различные уровни исполнения. В Fedora и OpenSUSE пользователь может закрыть X-сессию, набрав '''init 3''', а пользователям Debian/Ubuntu остается для переключения в безопасный режим только '''init 1'''.&lt;br /&gt;
&lt;br /&gt;
=== Пустой экран ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Спецрепортаж-15.png|thumb|Изменить разрешение экрана можно не только редактируя файл Xorg.conf, но и через панель настройки Nvidia.]]Инсталлятор ATI или Nvidia попытается изменить настройки вашего экрана для согласования с новым устройством. После установки вам нужно будет запустить '''gdm''' (или '''kdm''' для пользователей KDE) от имени root, чтобы активировать менеджер входа в систему. Если вы получите пустой экран, нужно будет либо вручную отредактировать '''/etc/X11/xorg.conf''', либо запустить входящую в ваш дистрибутив утилиту настройки экрана. Учтите: '''xorg.conf''' не для малодушных. Это технический файл, включающий спецификации вашего оборудования, например, возможности экрана, а также установки драйверов. Вот несколько вещей, которые нужно проверить, если вы натолкнетесь на проблемы:&lt;br /&gt;
* Убедитесь, что в секции Device конфигурационного файла подгружается правильный драйвер. Здесь должно быть либо «Driver ‘nvidia’», либо «Driver ‘fglrx’», в зависимости от вашего оборудования.&lt;br /&gt;
* Разрешение экрана может выходить за пределы возможностей вашего монитора. В этом случае создайте безопасное разрешение, оставив только 800х600 для всех элементов Display в секции Screen.&lt;br /&gt;
* Драйвер ядра может не загружаться. Наберите '''lsmod | grep “nvidia\| fglrx”'''. Если на выходе ничего не окажется, введите либо '''modprobe nvidia''', либо '''modprobe fglrx''', для загрузки модуля драйвера.&lt;br /&gt;
&lt;br /&gt;
После установки нового драйвера ваша Linux-система сможет поддерживать графику с 3D-ускорением.&lt;br /&gt;
&lt;br /&gt;
=== Следим за перегревом ===&lt;br /&gt;
&lt;br /&gt;
Когда ваша система работает под нагрузкой, вполне естественно, что ее компоненты перегреваются. Мощная видеокарта весьма способствует этой проблеме: без адекватного охлаждения могут начаться всякие странные вещи. Мы сказали «странные вещи», а не что-то более определенное, поскольку невозможно предсказать, что именно может случиться. На каком-то этапе возникают ошибки, обрушиваются приложения, повреждается изображение на экране, а то и система полностью зависает. А похоже это все на ошибки памяти.&lt;br /&gt;
&lt;br /&gt;
Отследить такие ошибки трудно, потому что за время перезагрузки машины оборудование охлаждается, и система опять работает как следует. Если вы заподозрили, что причиной проблем может быть перегрев, запустите инструмент слежения за температурами системы: это хорошо даже в том случае, если проблем и нет. Вывод предупреждения, что ваша система «разгорячилась» – прекрасный способ пресечь проблемы до того, как они возникли.&lt;br /&gt;
&lt;br /&gt;
Многие современные машины выводят информацию о температуре в каталог '''/proc/acpi/thermal_zone/''' в файловой системе. Если нет, попробуйте ввести '''modprobe thermal''' от имени root. Кроме того, существуют инструменты для мониторинга температуры и предупреждения о проблемах. Есть лишь один реальный претендент на роль лучшего приложения мониторинга: пакет под названием ''Lm-sensors''. Мониторинг – это приложение уровня ядра, и когда ''Lm-sensors'' будет установлен, его собственные драйверы смогут собирать все необходимые данные.&lt;br /&gt;
&lt;br /&gt;
Установка обычно сводится к поиску ‘lm-sensor’ в менеджере пакетов вашего дистрибутива, кроме того, имеет смысл установить графическую оболочку, например, не зависящий от рабочего стола Xsensors (для KDE попробуйте ''Ksensors''). Когда он будет установлен, запустите сценарий настройки из командной строки с правами root. Просто наберите '''sensors-detect''' и нажимайте [Enter] для каждого ответа по умолчанию. По завершении, скрипт попросит вас скопировать и вставить секцию в файл '''/etc/modules'''. Это обеспечит загрузку драйверов сенсоров при следующей перезагрузке системы, и вы сможете получить доступ к температурным данным, запустив '''sensors''' из командной строки или через одну из графических оболочек, установленных одновременно с ''Lm-sensors''.&lt;br /&gt;
&lt;br /&gt;
=== От молчания к звучанию ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Спецрепортаж-16.png|thumb|Звук можно оживить, всего лишь загрузив настройки микшера и подвигав &amp;quot;бегунки&amp;quot;]]Еще один источник головной боли – отсутствие звука. Без сомнения, современная звуковая подсистема в Linux очень совершенна, но она также слишком сложна, и поиски первичной причины беззвучия – занятие неблагодарное. Прежде всего проверьте все таблицы. Если вы не меняли конфигурацию оборудования, очень важно удержаться от попыток расковырять провода и динамики. Если раньше все работало, значит, настройки правильные. Возня с ними, пусть даже вы уверены, что здесь-то и причина проблемы, чревата лишь новыми бедами.&lt;br /&gt;
&lt;br /&gt;
Проверьте программный микшер (особенно если вы недавно модернизировали свою машину). Лучший способ это сделать – запустить какой-нибудь аудиофайл в настольном плейере и экспериментировать с уровнями различных каналов в вашем микшере. Если интерфейс командной строки в ''Alsamixer'' на ваш взгляд скудноват, можете установить и использовать инструмент под названием ''Alsamixergui''.&lt;br /&gt;
&lt;br /&gt;
Каналы, на которые следует обратить внимание – Master, PCM и Aux, но проблема со звуком в Linux заключается в том, что функции этих каналов не всегда очевидны. Например, обычная проблема – «бегунок» IEC: чтобы звук начал воспроизводиться, иногда его нужно выставить на 25%, а иногда на 0%. Поиграйте с ним, пока что-нибудь не услышите.&lt;br /&gt;
&lt;br /&gt;
{{Врезка&lt;br /&gt;
|Заголовок=Шаг за шагом: Устанавливаем драйверы Nvidia&lt;br /&gt;
|Содержание=Оборудование Nvidia – популярный выбор среди пользователей Linux, поскольку оно предоставляет лучшую 3D-производительность, которую только можно купить. Если вы любите играть или вам нужно работать с ПО для 3D-моделирования, вопрос производительности является существенным. Необходимое условие для инсталляции драйверов Nvidia – установленный исходный код вашего Linux-ядра. Прежде чем приступить к установке драйвера, откройте менеджер пакетов вашего дистрибутива и установите пакет исходных текстов. Есть шанс обойтись и без этого, если Nvidia уже предоставляет двоичный драйвер для вашего ядра. В противном случае просто следуйте этим шагам, войдя в систему как root.&lt;br /&gt;
{{{!}}&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-4.png|thumb|center]]&lt;br /&gt;
* '''Скачивание драйвера'''&lt;br /&gt;
Закройте ''X Window'' или загрузитесь в консоль. Вы всегда сможете скачать последний драйвер из консоли, используя web-браузер ''Lynx''. Введите lynx http://www.nvidia.com/object/unix.html, найдите ссылку для скачивания и нажмите &amp;lt;d&amp;gt;.&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-5.png|thumb|center]]&lt;br /&gt;
* '''Запуск скрипта установки'''&lt;br /&gt;
Введите '''sh''', а затем – имя полученного файла. Если инсталлятор возмущается, что вы не закрыли X, удалите '''/tmp/.X11-unix''' и '''/tmp/.X11-lock''' и попробуйте снова. Процесс установки выполняется автоматически; инсталлятор изменит ваш файл '''Xorg.conf'''.&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-6.png|thumb|center]]&lt;br /&gt;
* '''Проверка'''&lt;br /&gt;
Модуль ядра будет собран и установлен. Для гарантированной его загрузки вы можете ввести '''modprobe nvidia'''. После этого остается либо перезагрузить машину, либо запустить менеджер входа в систему – ''gdm'' или ''kdm''.&lt;br /&gt;
{{!}}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Программное обеспечение ==&lt;br /&gt;
''Тот факт, что ПО в Linux свободно, позволяет сделать многое. Но свободное ПО зачастую идет без свободной поддержки...''&lt;br /&gt;
&lt;br /&gt;
{{Врезка|right|Ширина=400px&lt;br /&gt;
|Заголовок=«Скорая помощь» по программам&lt;br /&gt;
|Содержание=&lt;br /&gt;
* Ближайший аналог инсталляционных файлов '''setup.exe''' в Linux – это Autopackage. Их довольно сложно делать, но если они доступны, то ПО устанавливается просто вихрем. Autopackage-файлы для последних релизов ''Gimp'', ''Gaim'' и ''Inkskape'' находятся на http://autopackage.org.&lt;br /&gt;
* Если вам нужно запускать системный скрипт во время загрузки, просто разместите ссылку на этот скрипт в каталоге '''/etc/rc.local'''. Как вариант, пользователь может добавить скрипт к своей Gnome-сессии из меню System &amp;gt; Preferences &amp;gt; Sessions, или кинуть ссылку в '''~/.kde/Autostart''' в случае KDE.&lt;br /&gt;
* Настройки рабочего стола можно найти в директориях '''.gnome''' или '''.kde''' в вашем домашнем каталоге. Копирование всего содержимого этих каталогов в другую систему перенесет большинство ваших системных установок, при условии, что вы используете одинаковые версии рабочих столов {{oncolor||green|[и не забудете сменить права доступа к файлам: пользователь «user» в дистрибутиве A и дистрибутиве Б – разный пользователь, – прим. ред.]}}.&lt;br /&gt;
* Менеджер пакетов можно использовать как для установки, так и для удаления ПО. Если вы ощутили недостаток места на диске, вспомните, что можно освободить немного места, удалив неиспользуемые приложения.&lt;br /&gt;
* Вы можете конвертировать RPM в Deb и наоборот, используя удобную утилиту под названием ''Alien''. Создаваемые ею пакеты в критических для системы приложениях использовать не следует, но это может реально помочь, если никакие другие пакеты не доступны. См. http://kitenet.net/~joey/code/alien.html.}}&lt;br /&gt;
'''ПО – сложная штука. Невозможно охватить все, поскольку Linux – одна из самых распространенных и используемых ОС на планете. И она бесконечно разнообразна. Каждый из нас так или иначе сталкивается с программными проблемами. И все-таки многие проблемы возникают чаще, чем должны бы. В основном это связано с обычным для свободного и открытого ПО недостатком документации – все меняется слишком быстро, чтобы технические писатели поспевали за разработкой. А если вы разработчик-одиночка, документация обычно расположена слишком низко в списке приоритетов.'''&lt;br /&gt;
&lt;br /&gt;
Хороший пример – композитный менеджер ''Compiz'' для сногсшибательных 3D-эффектов. Год назад он был на этапе формирования и вышел в январе 2006 года. Но за последние 12 месяцев программа созрела, к ней появились расширения, и в доказательство реального прогресса, проект распался на два (вторая ветвь известна как Beryl). Однако, несмотря на весь этот «прогресс», от жаждущих трехмерного куба чаще всего приходится слышать вопрос: а как заставить его работать? А жаждут практически все.&lt;br /&gt;
&lt;br /&gt;
=== «Ломаем» Compiz ===&lt;br /&gt;
&lt;br /&gt;
Для тех, кто хочет получить последний ''Compiz/Beryl'', жизнь недавно стала заметно проще, благодаря тому, что большинство современных дистрибутивов использует сервер ''X.org'' с активированным ''AIGLX''. Использование ''AIGLX'' означает, что больше не нужно менять используемый по умолчанию сервер ''X Window'' на ''Xgl''. Первоначально для многих пользователей это было основным камнем преткновения. Теперь остается лишь убедиться, что для вашей видеокарты есть драйверы, поддерживающие аппаратное ускорение (см. раздел «Оборудование»), и один из пакетов – ''Compiz'' или ''Beryl'' – установлен с помощью менеджера пакетов вашего дистрибутива.&lt;br /&gt;
&lt;br /&gt;
Если пакеты не предоставляются по умолчанию, потребуется добавить сторонний репозиторий. Например, в последней версии Ubuntu нужно добавить репозиторий ''Beryl'' (Ubuntu Beryl Repository, http://ubuntu.beryl-project.org) для загрузки пакетов ПО, прежде чем приступать к установке. Затем выполните '''Beryl-manager''' из командной строки – и текущая оконная рамка превратится в трясущееся желе.&lt;br /&gt;
&lt;br /&gt;
=== Идем в ногу со временем ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Спецрепортаж-17.png|thumb|Ubuntu позволяет добавлять различные источники для вашего ПО через приложение Software Sources]]С «красотой» мы разобрались; следующий наиболее популярный вопрос – как устанавливать файлы из Интернета. Ответить на него сложно, поскольку здесь нет простого решения. В Linux нет эквивалента скачивания программы '''setup.exe''' и ее запуска, как делается в Microsoft Windows. Менеджер пакетов дистрибутива ближе всего подходит к установке «в один клик», но он полностью зависит от дистрибутива, обеспечивающего пакеты для нужных вам приложений. Mandriva пытается отслеживать запросы публики и предоставлять пакеты для наиболее востребованных приложений, а Ubuntu и Debian включают тысячи прекомпилированных пакетов для установки.&lt;br /&gt;
&lt;br /&gt;
Но с появлением нового релиза вы застреваете. Каждому охота скачать и установить последнюю версию приложения, но если вам нужны официальные пакеты, то придется подождать следующего официального релиза выбранного вами дистрибутива. Это одна из причин, почему так много людей мечутся от одного дистрибутива к другому – они бегут с корабля, чтобы получить новейшую версию пакета, недоступную в настоящее время в их текущем дистрибутиве.&lt;br /&gt;
&lt;br /&gt;
Несмотря на это, есть несколько способов получить последнюю версию желанного ПО. Например, ''Mozilla Firefox'' доступен в виде статически собранного исполняемого файла – вы можете запустить эту программу сразу же, как скачаете, без размышлений о зависимостях и сценариях настройки. Вы также обнаружите, что готовые пакеты часто предоставляют сторонние разработчики (например, команда ''Beryl'' – свое композитное ПО), и установка их разработок обычно сводится к добавлению нового сервера в вашем менеджере пакетов до того, как вы решите установить свежее ПО.&lt;br /&gt;
&lt;br /&gt;
=== С исходным кодом на «ты» ===&lt;br /&gt;
&lt;br /&gt;
Если вам так уж нужна наисвежайшая версия, временами нет другого способа ее получить, кроме как скачать «голый» исходный код. Вид его зависит от вкуса автора, но наиболее общий метод распространения программ – упаковка исходного кода в файлы '''.tar.gz''' или '''.tar.bz2'''. Собирая свое ПО, легко нарваться на неприятности, и вообще-то это следует рассматривать как крайность – но большинство приложений можно собрать, следуя простой стандартной процедуре.&lt;br /&gt;
&lt;br /&gt;
Первый шаг – убедиться, что на вашей машине установлено необходимое для сборки окружение: не только инструменты компилятора GNU, но и версии «для разработчика» всех библиотек, нужных вашей программе. Это зависимости в чистом виде, и вы можете определить их, читая сопроводительную документацию. Поняв, какие пакеты вам нужно установить, убедитесь, что вы устанавливаете ‘dev’-версию из менеджера пакетов вашего дистрибутива – это те самые файлы «для разработчика», которые нужны для сборки вашего приложения.&lt;br /&gt;
&lt;br /&gt;
При установленных зависимостях большинство приложений требуют запуска '''./configure''' и '''make''' в созданном каталоге. Именно здесь и встречаются проблемы, когда процесс сборки не может найти библиотеку или файл, от которых он может зависеть. Хитрость тут в том, чтобы найти в выводе место возникновения первой ошибки и внимательно прочитать текст, чтобы найти, какой файл пропущен.&lt;br /&gt;
&lt;br /&gt;
Типичная ошибка может выглядеть как-то так: ‘'''libguile.h''': No such file or directory’. В данном случае не найден файл '''libguile.h'''. Как правило, вы сможете определить, какой пакет нужно установить, поискав этот файл в менеджере пакетов вашего дистрибутива или даже в Интернете. В случае с Debian/Ubuntu, хороший ресурс – www.debian.org/distrib/packages. Чтобы найти необходимый для решения проблемы пакет, вы можете ввести '''‘libguile.h’''' в поле «Search The Contents Of Packages» на этой странице. В нашем примере нехватает пакета '''libguile-dev''', его можно установить с помощью ''Synaptic''. С другой стороны, владельцы Mandriva могут поискать файлы, используя графический менеджер пакетов или набрав в командной строке '''urpmf libguile-dev''' от имени root. Компиляция проблемного ПО – это вопрос внимательного просмотра сообщений об ошибках, пока не будут выполнены все недокументированные требования.&lt;br /&gt;
&lt;br /&gt;
=== Пестрота мультимедиа ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Спецрепортаж-18.png|thumb|Новый инструмент пакетного менеджмента в Mandriva – один из простейших в использовании, он делает обработку зависимостей почти безболезненной.]]Что касается установки ПО, большинство пользователей, заполучив свой сияющий новизной Linux, первым делом желает либо послушать музыку в формате MP3, либо посмотреть в онлайне видео, закодированное с использованием проприетарного формата. Проблема заключается в том, что команды большинства дистрибутивов не хотят вступать в конфликт с законом, включая технологии, которые могут чем-то нарушить права на интеллектуальную собственность. MP3 – хороший пример, поскольку патент на его дизайн активно навязывается французской технологической компанией Thomson Consumer Electronics. Многие команды выбирают безопасную тропинку, оставляя его за пределами своего дистрибутива, поэтому-то открытые форматы, типа Ogg Vorbis, столь хорошо поддерживаются поставщиками дистрибутивов.&lt;br /&gt;
&lt;br /&gt;
Несмотря на эти ограничения, обычно есть возможность заставить большинство файловых форматов прекрасно работать в Linux. Например, разработанная сообществом версия RealPlayer для Linux включает лицензированное воспроизведение MP3 (см. www.real.com/linux). Но есть также возможность добавить поддержку различных форматов при помощи пакетов и репозиториев сторонних производителей. Активация Multiverse в Ubuntu позволит вам скачать пакет кодеков Win32, включающий поддержку всевозможных проприетарных форматов, а Penguin Liberation Front поддерживает также репозитории для Mandriva.&lt;br /&gt;
&lt;br /&gt;
{{Врезка&lt;br /&gt;
|Заголовок=Шаг за шагом: Добавление репозитория в Ubuntu&lt;br /&gt;
|Содержание=Один из наиболее частых вопросов, получаемых в Linux Format – как активировать сторонние или неподдерживаемые репозитории для вашего дистрибутива. Понятно, что процесс в каждом дистрибутиве свой, но поскольку Ubuntu – это хороший выбор для начинающих, то вот вам инструкция.&lt;br /&gt;
{{{!}}&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-7.png|thumb|center]]&lt;br /&gt;
* '''Выбор источников'''&lt;br /&gt;
Запустите менеджер пакетов Synaptic, затем отметьте Settings &amp;gt; Repository. Откроется новое приложение Select Sources, в котором вы сможете активировать новые репозитории на вкладке Third Party или добавить собственный, щелкнув на New.&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-8.png|thumb|center]]&lt;br /&gt;
* '''Скачивание'''&lt;br /&gt;
Когда бы вы ни сделали изменения в базе пакетов, Synaptic потребует обновить список доступных пакетов. Просто щелкните на Reload в Synaptic, чтобы скачать новый список пакетов с различных репозиториев.&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-9.png|thumb|center]]&lt;br /&gt;
* '''Поиск!'''&lt;br /&gt;
Каждый поиск приложения теперь будет охватывать новые источники пакетов, используете ли вы Synaptic или apt в командной строке. Это самый безопасный способ добавить ПО, но сторонние пакеты могут оказаться проблемными.&lt;br /&gt;
{{!}}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Сеть и администрирование ==&lt;br /&gt;
''В наши дни грош цена тем, кто не подключен к Интернету.''&lt;br /&gt;
&lt;br /&gt;
{{Врезка|right|Ширина=400px&lt;br /&gt;
|Заголовок=«Скорая помощь» по сетям и администрированию                                                                               &lt;br /&gt;
|Содержание=&lt;br /&gt;
* Существует множество беспроводных устройств, не поддерживаемых в Linux. Но часто их можно заставить работать, используя комбинацию Windows-драйвера и превосходное Linux-приложение по имени ''Ndiswrapper''. Он объединяет эмуляцию Windows с магией Linux, чтобы вернуть оборудование к жизни.&lt;br /&gt;
* Брандмауэры зачастую понимаются неправильно, потому что пользователям Windows вдалбливают, что он должен быть у них установлен. Истина же в том, что если у вас нет портов или сетевых сервисов, запущенных на вашей машине, то нужды в брандмауэре никакой нет – вот почему Ubuntu не поставляется с преднастроенным брандмауэром.&lt;br /&gt;
* Если вам нужно администрировать вашу систему удаленно, попробуйте установить программу ''Webmin''. Она позволит настраивать почти все аспекты работы вашей машины, от web-сервера до пользовательских учетных записей, и все это через браузер на удаленной машине.&lt;br /&gt;
* Сетевые USB-устройства, от старых телефонных модемов до новых ADSL, создают проблемы. Вы можете заставить их работать, но обычно это не стоит затраченных усилий. Гораздо проще купить дешевый ADSL-маршрутизатор и использовать подключение по Ethernet-кабелю – и никакой специальной настройки не потребуется.&lt;br /&gt;
* Таблицу маршрутизации (слегка запутанную) можно просмотреть, набрав '''route''' от имени root. Если у вас больше одного сетевого устройства, убедитесь, что только один маршрут отмечен как используемый по умолчанию. Можете удалить любые дополнительные маршруты по умолчанию, набрав '''route del default eth0''', только замените ‘eth0’ на имя соответствующего устройства.}}&lt;br /&gt;
&lt;br /&gt;
'''В Linux вы недалеко уйдете без подключения к сети. Несмотря на это, сейчас нет стандартного приложения для его настройки. В каждом дистрибутиве свой подход к поддержке сети, и как правило, предлагается собственная панель конфигурации или скрипт для настройки вашего соединения, а это вам не сильно поможет, если что-то поломается.'''&lt;br /&gt;
&lt;br /&gt;
Если ваша машина отказывается выходить в Интернет, можно попробовать несколько вещей. Наиболее обычная помеха в плохо настроенной сети – ваш компьютер не может преобразовать имя сервера в IP-адрес, необходимый для установления соединения. То есть если вы наберете что-то типа ‘bbc.co.uk’ в своем браузере, сетевой уровень, отвечающий за установление соединения, будет нуждаться в конвертации его в номер, или IP-адрес. Например, bbc.co.uk на самом деле соответствует IP-адресу 212.58.228.155.&lt;br /&gt;
&lt;br /&gt;
Одно в другое конвертирует DNS, сервер доменных имен. Если он не настроен, вы не сможете просматривать страницы, используя доменные имена, но тем не менее сможете использовать IP-адреса. Вот и первый ключ к решению проблемы – если доступ по IP-адресам работает, а по доменному имени – нет, значит, проблема в настройке DNS. Обычно это означает, что вы ввели неправильный адрес сервера. Адрес DNS вашего провайдера размещается в файле '''/etc/resolv.conf''', и вам нужно проверить, что после слова ‘nameserver’ указан правильный адрес.&lt;br /&gt;
&lt;br /&gt;
=== Общее соединение ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Спецрепортаж-19.png|thumb|Использование инструмента типа Firestarter для настройки брандмауэра сильно упрощает установку общего интернет-соединения.]]У многих из нас сейчас больше одного компьютера, которые без интернет-соединения полезны лишь наполовину. Вы можете использовать беспроводную сеть, но есть также возможность разделять соединение, используя Ethernet-кабель, если два компьютера достаточно близко друг от друга. Если у вас нет коммутатора между этими двумя компьютерами, важно, чтобы используемый вами кабель был «перекрестным» (crossover), а не стандартным.&lt;br /&gt;
&lt;br /&gt;
В некоторых дистрибутивах общее соединение создается открытием панели управления на машине, подсоединенной к Интернету, и активацией соответствующей опции. Например, в Mandriva общее соединение может быть активировано на страницу Network &amp;amp; Internet в центре управления. Но в других дистрибутивах, особенно в Ubuntu, вам придется выполнять настройку вручную.&lt;br /&gt;
&lt;br /&gt;
Намного проще настроить обе машины, если сетевые соединения используют статические адреса, а не назначаемые автоматически – особенно для машины, с которой вы хотите разделять соединение. Потому что если вы хотите, чтобы машины использовали общее соединение, имея автоматически назначаемый IP-адрес, то придется учитывать дополнительную сложность в лице DHCP-сервера. Общее интернет-соединение складывается из двух элементов: маршрутизации пакетов (forwarding) и трансляции сетевых адресов (NAT), оба они реализуются с помощью ''Iptables'' {{oncolor||green|[строго говоря, это не совсем верно. Часть ядра, отвечающая за маршрутизацию, может работать и без Iptables, – прим. ред.]}}. Это сетевой инструмент, работающий на уровне ядра и отвечающий за управление сетевыми пакетами – обычно известный как брандмауэр. А установка брандмауэра – самый простой способ настроить общее интернет-соединение.&lt;br /&gt;
&lt;br /&gt;
''Firestarter'' – одна из наиболее популярных утилит настройки брандмауэра для Linux. При первом старте «мастер» быстрого запуска проведет вас по настройкам брандмауэра и созданию общего интернет-соединения. Он берет на себя большую часть забот по настройке ''Iptables'', а также предоставляет в реальном времени информацию о том, какой именно процесс работает с Интернетом.&lt;br /&gt;
&lt;br /&gt;
=== Потерянный пароль ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Спецрепортаж-20.png|thumb|Даже если вы присматриваете за системой, где больше одного пользователя, сейчас гораздо проще использовать графический инструмент администрирования, а не консоль.]]Пароли не особо важны, если ваш компьютер стоит себе в углу, без подключения к интернету, и вы его единственный пользователь. Но как только вашу машину захочет использовать кто-то еще или вы пожелаете войти в сеть, хороший пароль становится жизненно необходимым для безопасности вашей системы. Хороший пароль, однако, плох тем, что его сложно запомнить. Самый популярный пароль, вероятно, ‘password1’, который как минимум учел желательность смешения букв и цифр. Если вы еще помните свой пароль root, достаточно войти в систему как root и назначить пароль пользователя командой passwd username. А вдруг пароль для учетной записи root вы тоже забыли? В случае Ubuntu, где и учетной записи root нету, забыть свой пользовательский пароль означает здорово влипнуть.&lt;br /&gt;
&lt;br /&gt;
Тогда придется перезагрузить вашу систему либо в безопасный режим, либо в режим восстановления. Обычно это применяется для решения проблем с загрузкой, но также полезно и для получения доступа с правами root без пароля. Если вы пользователь Debian или Ubuntu, при виде загрузочного меню ''Grub'' нажмите &amp;lt;Escape&amp;gt; и выберите загрузку ядра в режиме восстановления. По завершении процесса загрузки можно будет изменить пользовательский пароль обычным образом.&lt;br /&gt;
&lt;br /&gt;
=== ...теперь отдыхайте! ===&lt;br /&gt;
&lt;br /&gt;
Интернет полнится людьми, перенастраивающими свои дистрибутивы Linux, и мы отметили в начале, что для некоторых это весьма привлекательно. Продравшись сквозь проблемы и сумев самостоятельно их устранить, вы испытаете чувство подлинного удовлетворения. Это обряд посвящения для каждого пользователя Linux.&lt;br /&gt;
&lt;br /&gt;
Мы надеемся, что вы насобирали достаточно информации, способной помочь вам при любых проблемах; мы, как минимум, дали вам хорошую отправную точку для поиска решения. Но мы будем рады, если вы обратитесь к нам со своими сложностями. Можете также посетить наши дружелюбные форумы (www.linuxforum.ru). Linux зиждется на чувстве взаимопомощи; именно так мы делаем мир лучше. [http://www.linuxformat.ru LXF]&lt;br /&gt;
&lt;br /&gt;
{{Врезка&lt;br /&gt;
|Заголовок=Шаг за шагом: Использование менеджера настройки&lt;br /&gt;
|Содержание=Долгое время беспроводные сети причиняли в Linux настоящие мучения. К счастью, две утилиты берут на себя большую часть головной боли, связанной с этим процессом. Менеджеры настройки сети Gnome и KDE – это нововведения, которые, по сути, идентичны. Они выступают как интерфейс между вашим сетевым оборудованием и беспроводной сетью и позволяют вам сканировать доступные сети, сохраняя профиль для тех, которые вы будете использовать. Это значительное усовершенствование по сравнению с панелью управления старых дистрибутивов. Для начала воспользуйтесь своим менеджером пакетов, чтобы установить либо Gnome network-manager, либо KNetworkManager.&lt;br /&gt;
{{{!}}&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-10.png|thumb|center]]&lt;br /&gt;
* '''Подготовка'''&lt;br /&gt;
Вам может потребоваться отредактировать файл '''/etc/network/interfaces'''. Он содержит вашу текущую фиксированную беспроводную конфигурацию, которую нужно будет закомментировать, чтобы менеджер настройки сети смог использовать собственные установки.&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-11.png|thumb|center]]&lt;br /&gt;
* '''Запуск'''&lt;br /&gt;
Установленный и запущенный менеджер настройки сети можно будет найти на панели рабочего стола. Щелкните по иконке, чтобы открыть список доступных сетей, наряду с индикатором уровня сигнала и значком замка или щита, отмечающим зашифрованные сети.&lt;br /&gt;
{{!}}[[Изображение:LXF90-Спецрепортаж-12.png|thumb|center]]&lt;br /&gt;
* '''Соединение'''&lt;br /&gt;
Если вы выбираете незашифрованную сеть, интернет-соединение установится автоматически. Если сеть требует ввода ключа, появится окно запроса, чтобы вы ввели в него дополнительную информацию. Если данные введены правильно, соединение будет установлено.&lt;br /&gt;
{{!}}}&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-12.png</id>
		<title>Файл:LXF90-Спецрепортаж-12.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-12.png"/>
				<updated>2008-03-23T21:52:57Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-11.png</id>
		<title>Файл:LXF90-Спецрепортаж-11.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-11.png"/>
				<updated>2008-03-23T21:52:49Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-10.png</id>
		<title>Файл:LXF90-Спецрепортаж-10.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-10.png"/>
				<updated>2008-03-23T21:52:35Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-20.png</id>
		<title>Файл:LXF90-Спецрепортаж-20.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-20.png"/>
				<updated>2008-03-23T21:47:55Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-19.png</id>
		<title>Файл:LXF90-Спецрепортаж-19.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-19.png"/>
				<updated>2008-03-23T21:47:47Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-9.png</id>
		<title>Файл:LXF90-Спецрепортаж-9.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-9.png"/>
				<updated>2008-03-23T21:44:26Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-8.png</id>
		<title>Файл:LXF90-Спецрепортаж-8.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-8.png"/>
				<updated>2008-03-23T21:44:16Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-7.png</id>
		<title>Файл:LXF90-Спецрепортаж-7.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-7.png"/>
				<updated>2008-03-23T21:44:09Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-18.png</id>
		<title>Файл:LXF90-Спецрепортаж-18.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-18.png"/>
				<updated>2008-03-23T21:41:31Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-17.png</id>
		<title>Файл:LXF90-Спецрепортаж-17.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-17.png"/>
				<updated>2008-03-23T21:41:15Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-6.png</id>
		<title>Файл:LXF90-Спецрепортаж-6.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-6.png"/>
				<updated>2008-03-23T21:38:06Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-5.png</id>
		<title>Файл:LXF90-Спецрепортаж-5.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-5.png"/>
				<updated>2008-03-23T21:38:06Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-4.png</id>
		<title>Файл:LXF90-Спецрепортаж-4.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-4.png"/>
				<updated>2008-03-23T21:37:43Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-15.png</id>
		<title>Файл:LXF90-Спецрепортаж-15.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-15.png"/>
				<updated>2008-03-23T21:34:56Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-16.png</id>
		<title>Файл:LXF90-Спецрепортаж-16.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-16.png"/>
				<updated>2008-03-23T21:33:36Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-14.png</id>
		<title>Файл:LXF90-Спецрепортаж-14.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-14.png"/>
				<updated>2008-03-23T21:31:36Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-13.png</id>
		<title>Файл:LXF90-Спецрепортаж-13.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-13.png"/>
				<updated>2008-03-23T21:31:24Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-3.png</id>
		<title>Файл:LXF90-Спецрепортаж-3.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-3.png"/>
				<updated>2008-03-23T19:57:45Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-2.png</id>
		<title>Файл:LXF90-Спецрепортаж-2.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-2.png"/>
				<updated>2008-03-23T19:57:35Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-1.png</id>
		<title>Файл:LXF90-Спецрепортаж-1.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-%D0%A1%D0%BF%D0%B5%D1%86%D1%80%D0%B5%D0%BF%D0%BE%D1%80%D1%82%D0%B0%D0%B6-1.png"/>
				<updated>2008-03-23T19:57:29Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/LXF90:JavaEE</id>
		<title>LXF90:JavaEE</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/LXF90:JavaEE"/>
				<updated>2008-03-21T12:39:42Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Цикл/Java EE}}&lt;br /&gt;
== {{oncolor||red|Телефонная книга}}: переход на JSP ==&lt;br /&gt;
''{{oncolor||red|ЧАСТЬ 2}} Встречают по одежке – и Большой Босс не был сильно впечатлен созданной нами в прошлый раз адресной книгой. '''Александр Бабаев''' исправляет замеченные недочеты.''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
В прошлый раз мы создали простейшую электронную записную книжку. Она работает в браузере и показывает несколько простых страничек, на которых можно просмотреть список контактов, добавить новый контакт, удалить его или отредактировать. А сейчас давайте попробуем сделать все это более правильно.&lt;br /&gt;
&lt;br /&gt;
=== Почему было плохо? ===&lt;br /&gt;
&lt;br /&gt;
Действительно, почему? Работает, и хорошо. Достаточно быстро и не слишком сложно. Но вдруг захочется поменять дизайн страничек? А захочется через десять минут работы. Или после того, как страничку посмотрит начальник.&lt;br /&gt;
&lt;br /&gt;
Чтобы сделать это, можно изменить код проекта, потом перекомпилировать его, остановить сервер (А? Кто-то работал? Извините...), установить новый код и повторно запустить сервер. Метод, мягко говоря, неудобный. А можно изменить сам проект так, чтобы выполнение таких пожеланий не требовало столь сложных действий. Второй путь зовется рефакторингом и гораздо более корректен. Если разделить дизайн и логику работы приложения (бизнес-логику), то в дальнейшем можно будет, например, разделить и работу по их поддержанию. Хороший программист не всегда создает хорошие пользовательские интерфейсы, поэтому данный аспект тоже важен.&lt;br /&gt;
&lt;br /&gt;
=== Как сделать хорошо? ===&lt;br /&gt;
&lt;br /&gt;
Ну, вкратце уже понятно. Нужно вынести в отдельные файлы ту часть, которая меняется часто (в нашем случае, это интерфейс) и как-то подключить эти файлы из нашей программы. Плюс, желательно сделать это так, чтобы формат файлов «дизайна» был стандартным, чтобы каждый раз не переучиваться.&lt;br /&gt;
&lt;br /&gt;
Решений для данной проблемы существует множество. Рассмотрим самые распространенные:&lt;br /&gt;
&lt;br /&gt;
* '''Шаблоны.''' Одна из самых распространенных библиотек работы с шаблонами – ''Velocity''. При использовании шаблонных движков можно добавлять в текст специальные вставки, которые говорят: «Тут вставить значение переменной {{oncolor||red|Name}}». Иногда можно делать более сложные операции (вставка подшаблонов, вычисления, условные вставки).&lt;br /&gt;
&lt;br /&gt;
* '''JSP (Java Server Pages).''' По времени появления, пожалуй, первая технология для отделения дизайна от бизнес-логики. Но я ее поставил второй, так как она сложнее, чем просто шаблонная библиотека. JSP позволяет внедрить код на (по задумке) любом языке программирования внутрь специальным образом созданной странички. Впрочем, обычно используется Java. Теоретически, можно написать серверное приложение, используя исключительно JSP. Этот подход похож на PHP, с тем отличием, что JSP-страницы – это полноценные сервлеты, они компилируются при обновлении исходного текста и обрабатываются как таковые.&lt;br /&gt;
&lt;br /&gt;
* '''JSF (Java Server Faces).''' В некотором роде эта технология объединяет подходы, которые используются при создании «обычных» и «сетевых» программ. Интерфейс (как дизайн интерфейса, так и его логика) программы описывается специальным образом, а после этого пишутся JSP-странички, в которых указывается «тут вставить таблицу с именем таким-то». JSF обрабатывает эти спецвставки и «рисует» функциональные элементы интерфейса (обрабатывая события от них и так далее), позволяя дизайнеру сосредоточиться на остальном.&lt;br /&gt;
&lt;br /&gt;
* '''Google Web Toolkit.''' Не могу не остановиться на этом средстве. При его использовании на выходе получается полноценное AJAX-приложение (что это такое – тема отдельной статьи, пример – Google Mail), а на входе – все тот же Java-код. Решение интересное, не лишенное своих достоинств и недостатков.&lt;br /&gt;
&lt;br /&gt;
Мы же в рамках данной статьи рассмотрим «средненькое» решение – Java Server Pages. В основном – из-за его стандартности, хотя для данного конкретного случая можно выбрать какой-нибудь шаблонный движок, например, тот же Velocity (http://velocity.apache.org).&lt;br /&gt;
&lt;br /&gt;
=== Общая схема работы приложения ===&lt;br /&gt;
&lt;br /&gt;
Поняв, что нужно отделить логику от дизайна, давайте подумаем, каким образом это можно сделать. Предлагаю остановиться на следующей схеме - '''(Рис. 1)'''.&lt;br /&gt;
&lt;br /&gt;
Сервлет выдает данные, абсолютно не заботясь о том, как они будут отображаться. Но выдает он их не в «сыром» виде, а в полностью обработанном, готовом для отображения на экране (например, если нужно полное имя человека, а в данных – его ФИО по отдельности, то сервлет должен преобразовать второе в первое перед передачей в JSP).&lt;br /&gt;
&lt;br /&gt;
Возникает вопрос: как же передаются данные от сервлета в JSP? Через уже известный нам объект {{oncolor||red|request}}. К нему «прикручен» специальный ассоциативный массив «{{oncolor||red|String – Object}}», который называется атрибутами и который живет, пока жив запрос. К нему имеет доступ и сервлет, и JSP-страница, поэтому его можно (и это правильно) использовать для передачи данных.&lt;br /&gt;
                                                                          &lt;br /&gt;
=== Переходим на Tomcat ===&lt;br /&gt;
&lt;br /&gt;
Но сначала нужно переписать наш сервлет «по-взрослому». Встроенный сервер – это замечательно для кустарных проектов, но обычно контейнер сервлетов уже стоит, и подключаться следует к нему.&lt;br /&gt;
&lt;br /&gt;
Мы будем использовать Tomcat 5.5. Это классический, можно даже сказать, стандартный открытый сервлет-контейнер. Для установки Tomcat достаточно просто скачать его с http://tomcat.apache.org (или взять с нашего DVD), распаковать и запустить '''bin/startup.sh''' (или соответсвующий '''.bat'''). ''Tomcat'' работает с файлами специального типа Web Archive (WAR). Обнаружив такой файл в определенном каталоге, Tomcat разворачивает его и запускает содержащееся в нем приложение. Чтобы перезапустить или обновить программу, достаточно просто заменить один WAR-файл другим.&lt;br /&gt;
&lt;br /&gt;
Предыдущий код не готов для работы с Tomcat, поэтому его нужно немного переписать. Вот что будет сделано:&lt;br /&gt;
&lt;br /&gt;
* '''{{oncolor||red|AddressBook}}''' потеряет методы {{oncolor||red|start}} и {{oncolor||red|main}} и превратится в простое хранилище записей.&lt;br /&gt;
* '''{{oncolor||red|AddressBookHandler}}''' превратится в {{oncolor||red|AddressBookServlet}}, и в него будет добавлено примерно следующее '''(Листинг 1)''':&lt;br /&gt;
&lt;br /&gt;
'''{{oncolor||red|Листинг 1. Новый AddressBook}}'''&lt;br /&gt;
&lt;br /&gt;
 private AddressBook _addressBook = null;&lt;br /&gt;
 &lt;br /&gt;
 public void init(ServletConfig aServletConfig) throws ServletException {&lt;br /&gt;
  super.init(aServletConfig);&lt;br /&gt;
  _addressBook = new AddressBook();&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 protected void doGet(HttpServletRequest aRequest, HttpServletResponse aResponse)&lt;br /&gt;
      throws ServletException, IOException&lt;br /&gt;
  handle(aRequest, aResponse);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 protected void doPost(HttpServletRequest aRequest, HttpServletResponse aResponse)&lt;br /&gt;
      throws ServletException, IOException                                &lt;br /&gt;
  handle(aRequest, aResponse);                                            &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Сам метод {{oncolor||red|handle}} тоже слегка преобразуется '''(Листинг 2)''':&lt;br /&gt;
&lt;br /&gt;
'''{{oncolor||red|Листинг 2. Новый метод handle}}'''&lt;br /&gt;
&lt;br /&gt;
  private void handle(HttpServletRequest aRequest, HttpServletResponse aResponse)&lt;br /&gt;
        throws ServletException, IOException {&lt;br /&gt;
   aRequest.setCharacterEncoding(“utf-8”);&lt;br /&gt;
 &lt;br /&gt;
   String target = aRequest.getRequestURI().substring(&lt;br /&gt;
     aRequest.getContextPath().length());&lt;br /&gt;
 &lt;br /&gt;
   if (target.equals(“/”)) {&lt;br /&gt;
   _drawer.outputPage(“index.jsp”, aRequest, aResponse);&lt;br /&gt;
   } else if (“/add”.equals(target)) {&lt;br /&gt;
   handleAdd(aRequest, aResponse);&lt;br /&gt;
   } else if (“/view”.equals(target)) {&lt;br /&gt;
   handleView(aRequest, aResponse);&lt;br /&gt;
   } else if (“/edit”.equals(target)) {&lt;br /&gt;
   handleEdit(aRequest, aResponse);&lt;br /&gt;
   } else if (“/remove”.equals(target)) {&lt;br /&gt;
   handleRemove(aRequest, aResponse);&lt;br /&gt;
   }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
* Для того, чтобы Tomcat «понял», что ему положили сервлет, и знал, как его обрабатывать, нужно написать специальный файл, который называется «дескриптор». Несмотря на то, что слово страшное, это просто XML-документ с описанием сервлета. Если перевести с языка написания дескрипторов на русский, то получится примерно следующая информация:&lt;br /&gt;
&lt;br /&gt;
** Наш сервлет называется {{oncolor||red|«ABServlet»}} и запускается классом {{oncolor||red|AddressBookServlet}}. Теоретически можно назвать сервлет так же, как и класс, но мы не будем так делать, чтобы было меньше путаницы.&lt;br /&gt;
&lt;br /&gt;
** Для всех URL, которые начинаются с «/», нужно вызывать сервлет, который называется ABServlet.&lt;br /&gt;
&lt;br /&gt;
А вот как он выглядит '''(Листинг 3)''':&lt;br /&gt;
&lt;br /&gt;
'''{{oncolor||red|Листинг 3. Дескриптор для сервлета}}'''&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;?xml version=”1.0” encoding=”UTF-8”?&amp;gt;&lt;br /&gt;
  &amp;lt;web-app version=”2.4”&lt;br /&gt;
     xmlns=”http://java.sun.com/xml/ns/j2ee”&lt;br /&gt;
     xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”&lt;br /&gt;
     xsi:schemaLocation=”http://java.sun.com/xml/ns/j2ee&lt;br /&gt;
     http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd” &amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;servlet&amp;gt;&lt;br /&gt;
   &amp;lt;display-name&amp;gt;AddressBook&amp;lt;/display-name&amp;gt;  &lt;br /&gt;
   &amp;lt;servlet-name&amp;gt;Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
   &amp;lt;servlet-class&amp;gt;AddressBookServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
   &amp;lt;load-on-startup&amp;gt;0&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;
   &amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
   &amp;lt;servlet-name&amp;gt;Servlet&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
   &amp;lt;url-pattern&amp;gt;/&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
   &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/web-app&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Дескриптор будет называться '''web.xml''' и храниться в специальном каталоге. Где именно – обсудим, когда будем собирать сервлет в {{oncolor||red|WAR}}&lt;br /&gt;
.&lt;br /&gt;
Сделайте указанные изменения самостоятельно или возьмите гото-вый код с DVD. Все в порядке? Тогда движемся дальше.&lt;br /&gt;
&lt;br /&gt;
=== Новый метод ===&lt;br /&gt;
&lt;br /&gt;
Если присмотреться более внимательно к коду нового {{oncolor||red|handle}}, можно заметить, что там появился вызов метода {{oncolor||red|outputPage}}. Раньше его, в отличие от разных {{oncolor||red|handle}}... не было. Это метод, который выбирает JSP-файл и передает ему управление для вывода страничек. Выглядит метод следующим образом '''(Листинг 4)''':&lt;br /&gt;
&lt;br /&gt;
'''{{oncolor||red|Листинг 4. Метод outputPage}}'''&lt;br /&gt;
&lt;br /&gt;
 public void outputPage(String aJSPName, HttpServletRequest aRequest, HttpServletResponse aResponse) throws IOException, ServletException&lt;br /&gt;
 {&lt;br /&gt;
  RequestDispatcher dispatcher = aRequest.getRequestDispatcher(“/jsps/” + aJSPName);&lt;br /&gt;
  dispatcher.forward(aRequest, aResponse);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
В этом методе мы берем нужный JSP-файл и говорим сервлет-контейнеру: «Обработай, пожалуйста». Остальное берет на себя контейнер. Он ищет JSP-файл, загружает его, компилирует (если это нужно), выполняет получившийся сервлет, а результат записывает в {{oncolor||red|aResponse}}.&lt;br /&gt;
&lt;br /&gt;
=== JSP-страницы ===&lt;br /&gt;
&lt;br /&gt;
Для начала создадим каталог, в котором будем собирать наше интернет-приложение. Назвать можно как угодно, например, {{oncolor||red|WebApp}} ({{oncolor||red|Web Application}}). В нем создадим специальный каталог '''WEB-INF''', где должен находиться дескриптор '''web.xml''', и каталог '''jsps''', в котором будут храниться JSP-странички.&lt;br /&gt;
&lt;br /&gt;
Создадим три JSP-файла: для индексной странички, для редактирования (или добавления) записей и для просмотра, и назовем их, соответственно, '''index.jsp''', '''edit.jsp''', '''view.jsp'''. Не забудьте – их нужно сохранить в в {{oncolor||red|WebApp/jsps}}.&lt;br /&gt;
&lt;br /&gt;
Сам JSP достаточно прост. Рассмотрим '''index.jsp''' '''(Листинг 5)''':&lt;br /&gt;
&lt;br /&gt;
'''{{oncolor||red|Листинг 5. index.jsp}}'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;%@ page contentType=”text/html; charset=UTF-8” %&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&lt;br /&gt;
   &amp;lt;meta http-equiv=”Content-Type” content=”text/html; charset=utf-8”/&amp;gt;&lt;br /&gt;
   &amp;lt;title&amp;gt;Адресная книга&amp;lt;/title&amp;gt;&lt;br /&gt;
  &amp;lt;/head&amp;gt;&lt;br /&gt;
  &amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Адресная книга&amp;lt;/h1&amp;gt;&lt;br /&gt;
   &amp;lt;a href=”&amp;lt;%=request.getContextPath()%&amp;gt;/add”&amp;gt;Добавить запись&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
   &amp;lt;a href=”&amp;lt;%=request.getContextPath()%&amp;gt;/view”&amp;gt;Просмотреть записи&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
  &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Первая строчка добавляет поле «Content-type» к HTTP-заголовку ответа. Это прямой аналог строки&lt;br /&gt;
&lt;br /&gt;
 aRequest.setContentType(“text/html; charset=utf-8”)&lt;br /&gt;
&lt;br /&gt;
из «старого» метода {{oncolor||red|handle}}. А дальше, кроме странных вставок {{oncolor||red|&amp;lt;%...%&amp;gt;}}, идет обычный HTML-код. И это хорошо! Это понятно! Теперь разберемся с непонятным.&lt;br /&gt;
&lt;br /&gt;
В JSP можно вставлять «инородный» для HTML код, который специальным образом интерпретируется сервером и может быть использован для вставки различных данных. Есть несколько типов таких вставок.&lt;br /&gt;
&lt;br /&gt;
* {{oncolor||red|&amp;lt;%@...%&amp;gt;}} – обозначает специальную вставку, которая определяет параметры страницы, в нашем случае – {{oncolor||red|ContentType}}. Можно задавать, например, язык, на котором написана страница. Он же используется для секций {{oncolor||red|import}} (см. '''view.jsp''' ниже).&lt;br /&gt;
* {{oncolor||red|&amp;lt;%&amp;amp;#61;...%&amp;gt;}} – это простой вывод переменной. Действие вставки {{oncolor||red|&amp;lt;%&amp;amp;#61;что-нибудь%&amp;gt;}} аналогично вызову {{oncolor||red|request.getWriter().write(что-нибудь)}}.&lt;br /&gt;
* {{oncolor||red|&amp;lt;%...%&amp;gt;}} – самый общий вариант вставки, внутри может быть любой код. В нашем случае, на Java.&lt;br /&gt;
&lt;br /&gt;
'''index.jsp''' – простой файл, посмотрим на нечто более сложное. Например, '''view.jsp''' '''(Листинг 6)'''.&lt;br /&gt;
&lt;br /&gt;
'''{{oncolor||red|Листинг 6. view.jsp}}'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 &amp;lt;%@ page contentType=”text/html; charset=UTF-8” %&amp;gt;&lt;br /&gt;
 &amp;lt;%@ page import=”java.util.*” %&amp;gt;&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
 &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Адресная книга&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
 &amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;Адресная книга, список контактов&amp;lt;/h1&amp;gt;&lt;br /&gt;
  &amp;lt;a href=”&amp;lt;%=request.getContextPath()%&amp;gt;”&amp;gt;На главную&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
  &amp;lt;span style=”color: green;”&amp;gt;&amp;lt;%=request.getAttribute(“message”)%&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;
  &amp;lt;table border=”1”&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&amp;lt;td width=”100”&amp;gt;Имя&amp;lt;/td&amp;gt;&amp;lt;td width=”100”&amp;gt;Номер&amp;lt;/td&amp;gt;&amp;lt;td width=”100”&amp;gt;Комментарий&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt; - &amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% Map numbers = (Map) request.getAttribute(“numbers”);&lt;br /&gt;
   Map comments = (Map) request.getAttribute(“comments”);&lt;br /&gt;
   for (Object entry : numbers.entrySet()) {&lt;br /&gt;
   String name = (String) ((Map.Entry) entry).getKey();&lt;br /&gt;
   String number = (String) numbers.get(name);&lt;br /&gt;
   String comment = (String) comments.get(name); %&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
   &amp;lt;td class=”name”&amp;gt;&amp;lt;%=name%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td class=”number”&amp;gt;&amp;lt;%=number%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td class=”comment”&amp;gt;&amp;lt;%=comment%&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
   &amp;lt;td class=”name”&amp;gt;&lt;br /&gt;
 &amp;lt;a href=”&amp;lt;%=request.getContextPath()%&amp;gt;/remove?number=&amp;lt;%=number%&amp;gt;”&amp;gt;Удалить&amp;lt;/a&amp;gt;&lt;br /&gt;
 &amp;lt;a href=”&amp;lt;%=request.getContextPath()%&amp;gt;/edit?number=&amp;lt;%=number%&amp;gt;”&amp;gt;Редактировать&amp;lt;/a&amp;gt;&lt;br /&gt;
   &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% } %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
 &amp;lt;/body&amp;gt;&lt;br /&gt;
 &amp;lt;/html&amp;gt;&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как можно заметить, здесь есть и импорт (о чем я говорил чуть выше), и вставка Java-кода. Данный файл отлично показывает, как, например (не самый лучший способ, конечно), сделать вывод в цикле.&lt;br /&gt;
&lt;br /&gt;
=== А как это обрабатывается-то? ===&lt;br /&gt;
&lt;br /&gt;
Естественно, и методы {{oncolor||red|handle}}... после такого изменения стали другими. Весь вывод HTML-кода исчез, осталась подготовка данных, и вызов метода {{oncolor||red|outputPage}}. Вот, например, метод {{oncolor||red|handleEdit(...)}} '''(Листинг 7)''':&lt;br /&gt;
&lt;br /&gt;
'''{{oncolor||red|Листинг 7. Метод handleEdit, обработка редактирования записи}}'''&lt;br /&gt;
&lt;br /&gt;
 if (aRequest.getParameter(“number”) == null) {&lt;br /&gt;
  _addressBook.removeContactByNumber(aRequest.getParameter(“number”));&lt;br /&gt;
  aRequest.setAttribute(“message”, “Не определено, что редактировать”);&lt;br /&gt;
  handleView(aRequest, aResponse);&lt;br /&gt;
 } else if (aRequest.getParameter(“edited”) != null) {&lt;br /&gt;
  _addressBook.editContact(aRequest.getParameter(“edited”),           &lt;br /&gt;
   aRequest.getParameter(“name”),                                     &lt;br /&gt;
   aRequest.getParameter(“number”),&lt;br /&gt;
   aRequest.getParameter(“comment”));&lt;br /&gt;
   aRequest.setAttribute(“message”, “Контакт \”” +&lt;br /&gt;
   aRequest.getParameter(“name”) + “\” отредактирован”);&lt;br /&gt;
  handleView(aRequest, aResponse);                                    &lt;br /&gt;
 } else {&lt;br /&gt;
  Contact contact = _addressBook.getContactByNumber(aRequest.getParameter(“number”));&lt;br /&gt;
  aRequest.setAttribute(“action”, “edit”);&lt;br /&gt;
  aRequest.setAttribute(“edit.name”, contact.getName());&lt;br /&gt;
  aRequest.setAttribute(“edit.number”, contact.getNumber());&lt;br /&gt;
  aRequest.setAttribute(“edit.comment”, contact.getComment());&lt;br /&gt;
  outputPage(“edit.jsp”, aRequest, aResponse);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Остальные методы меняются аналогично – их полный код можно найти на диске.&lt;br /&gt;
&lt;br /&gt;
=== И как все это вставить в Tomcat? ===&lt;br /&gt;
&lt;br /&gt;
Теперь у нас есть:&lt;br /&gt;
&lt;br /&gt;
* Классы {{oncolor||red|Contact}}, {{oncolor||red|AddressBook}}, {{oncolor||red|AddressBookServlet}}.&lt;br /&gt;
* Файл '''web.xml'''.&lt;br /&gt;
* Каталог '''jsps''' с файлами '''edit.jsp''', '''index.jsp''', '''view.jsp'''.&lt;br /&gt;
&lt;br /&gt;
Для того, чтобы Tomcat понял, что ему дали полноценное приложение, нужно выполнить всего три шага:&lt;br /&gt;
&lt;br /&gt;
* Скомпилировать все, что компилируется, и создать правильную иерархию файлов и каталогов, которая представлена '''на рис. 2'''.&lt;br /&gt;
* Создать специальный файл-описание архива («манифест»).&lt;br /&gt;
* Заархивировать созданную структуру при помоци утилиты ''jar'', входящей в комплект JDK.&lt;br /&gt;
&lt;br /&gt;
Скомпилируем файлы. Тут ничего нового не появилось, разве что изменилась сама команда (обратите внимание на ключ {{oncolor||red|-cp}}, задающий библиотеки {{oncolor||red|classpath}}):&lt;br /&gt;
&lt;br /&gt;
 cd ~/Programming/AddressBook/src&lt;br /&gt;
 javac -encoding utf-8 -cp ~/bin/tomcat/common/lib/servlet-api.jar -d ../build/WEB-INF/classes/ *.java&lt;br /&gt;
&lt;br /&gt;
Переходим к созданию манифеста. Он должен называться '''MANIFEST.MF''' и располагаться в каталоге '''META-INF'''. К счастью, за этим следит сам '''jar''', поэтому нам достаточно просто сохранить где-то файл и указать его '''jar'''’у как манифест. В нашем случае он предельно прост и не содержит интересной информации, но в принципе здесь могут располагаться всякие настройки для запуска вашего приложения. Вот его текст '''(Листинг 8)''':&lt;br /&gt;
&lt;br /&gt;
'''{{oncolor||red|Листинг 8. Манифест для war-файла}}'''&lt;br /&gt;
&lt;br /&gt;
 Manifest-Version: 1.0&lt;br /&gt;
 Created-By: Hands of programmer&lt;br /&gt;
&lt;br /&gt;
Теперь соберем все в {{oncolor||red|war}} (Web Archive). Манифест для приведенной ниже команды должен быть назван '''MANIFEST.MF''' и располагаться рядом с каталогом '''build'''. Результирующий архив называется '''address.war''' и располагается там же, рядом с манифестом.&lt;br /&gt;
&lt;br /&gt;
 jar -cfm ../address.war ../MANIFEST.MF *&lt;br /&gt;
&lt;br /&gt;
А сейчас наступает самый волшебный момент! Возьмите '''address.war''' и положите его в каталог webapps Tomcat’а. Подождите несколько секунд. Увидев новое приложение, Tomcat развернет его (появляется каталог с именем вашего war’а) и подключит к системе. После этого можно просто зайти в браузер и набрать:&lt;br /&gt;
&lt;br /&gt;
 http://localhost:8080/address/&lt;br /&gt;
&lt;br /&gt;
Вуаля, получите ваше приложение.&lt;br /&gt;
&lt;br /&gt;
=== И что теперь? ===&lt;br /&gt;
&lt;br /&gt;
А теперь можно менять JSP-файлы «на лету» в распакованном каталоге '''webapps/address/jsps'''. При этом будет автоматически происходить несколько действий, в результате которых файлы подхватятся приложением. Так меняется дизайн без перекомпиляции, без рестарта серверного приложения, как это у нас было до сих пор.&lt;br /&gt;
&lt;br /&gt;
Я считаю, что на данном этапе приложение «Адресная книга» работает хорошо. Оно выполняет свои несложные функции и умеет изменяться «на лету» по запросу пользователя. Оно простое – и это чуть ли не самое главное. Но есть еще достаточно аспектов, о которых стоит знать при разработке более сложных интернет-приложений. Мы рассмотрим их в следующих статьях данной серии. [http://www.linuxformat.ru LXF]&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/LXF90:Kerio_Mail_Server</id>
		<title>LXF90:Kerio Mail Server</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/LXF90:Kerio_Mail_Server"/>
				<updated>2008-03-20T20:12:20Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Новая: {{Карточка программы | name = Kerio Mail Server | screenshot = 200px | developer = Kerio Technologies Inc | latest_relea...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Карточка программы&lt;br /&gt;
| name = Kerio Mail Server&lt;br /&gt;
| screenshot = [[Изображение:LXF90-Kerio-1.png|200px]]&lt;br /&gt;
| developer = [[Kerio Technologies Inc]]&lt;br /&gt;
| latest_release_version = 6.3&lt;br /&gt;
| operating_system = [[Unix]]&lt;br /&gt;
| genre = [[Почтовый сервер]]&lt;br /&gt;
| license = Пропиетарная от €400 (лицензия на 10 пользователей)&lt;br /&gt;
| website = [http://www.kerio.com/ru www.kerio.com]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Kerio Mail Server 6.3 ==&lt;br /&gt;
''Вдоволь наигравшийся с макросами m4 '''Андрей Тусеев''' рассматривает альтернативу Sendmail, которую можно настроить одной мышью.''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
Пользователи Linux вряд ли могут жаловаться на недостаток почтовых серверов. Для идейных противников старого доброго ''Sendmail'' есть ''Postfix'', ''qmail' и множество других альтернатив; обеспечение доступа к почтовому ящику можно поручить как крохам вроде ''popa3d'', так и тяжеловесам: ''Cyrus'' и прочим. Для желающих иметь доступ к письмам даже из интернет-кафе, затерянного где-то в предгорьях Анд, есть ''SquirrelMail''. Богатый ассортимент – это прекрасно, но есть и обратная сторона медали – администратору, отвечающему за почтовый шлюз, необходимо изучить (а в дальнейшем – поддерживать) несколько различных продуктов, каждый из которых обладает собственными правилами (и тонкостями) настройки.&lt;br /&gt;
&lt;br /&gt;
Решения вроде ''Kerio Mail Server'' (KMS) стремятся устранить этот недостаток. Пришедшие из мира Windows, они являются комбайном типа «все в одном» и стремятся предоставить понятный и единообразный графический интерфейс, упрощающий сопровождение. Мы решили оценить плюсы и минусы этого подхода, установив ''Kerio Mail Server 6.3.1'' на систему под управлением CentOS 4.4, двоично совместимую с RHEL.&lt;br /&gt;
&lt;br /&gt;
=== Первое знакомство ===&lt;br /&gt;
&lt;br /&gt;
Продукт распространяется в виде RPM-пакета и поддерживает практически все распространенные серверные системы (можно отметить разве что отсутствие модного нынче Ubuntu 6.06 LTS): Red Hat Enterprise Linux 3/4, Fedora Core 4/5, SUSE Linux 10.0/10.1. Огорчает только отсутствие документации – в дистрибутиве ее нет совсем, а информация на сайте посвящена, в первую очередь, версии для Windows (впрочем, принципиальных отличий не так уж и много). После установки пакета вам будет предложено прочитать краткую справку, остановить сервисы ''Sendmail/Postfix'' и запустить утилиту ''cfgwizrd'' для первичной настройки сервера. ''Cfgwizard'' использует текстовый оконный интерфейс, что слегка удивляет – от коммерческого продукта обычно ждешь приятных графических мастеров. Тем не менее, со своей задачей мастер ''cfgwizard'' справляется без проблем. Вас попросят указать имя первичного почтового домена и его почтового хоста, которое, естественно, должно указывать на машину с запущенным ''Kerio Mail Server''. Настройка DNS-зон в обязанности мастера не входит, так что вам следует позаботиться об этом заранее. На следующем шаге создается учетная запись администратора почтового сервера, затем – указывается каталог для хранения почтовых сообщений, и – вуаля! Ваш сервер практически готов к работе – осталось только запустить его командой '''/etc/init.d/keriomailserver start'''. В целом, процесс первичной настройки сервера в Linux повторяет таковой в Windows, что весьма порадует мигрантов с этой ОС.&lt;br /&gt;
&lt;br /&gt;
=== Гюльчатай, открой личико! ===&lt;br /&gt;
&lt;br /&gt;
Управление работающим сервером осуществляется посредством графической консоли, запускаемой командой kerioadmin. Если разработчики ''Kerio Mail Server'' задавались целью выдержать ее в духе традиционного для Unix графического инструментария (Motif, конечно... А вы что подумали?), то им это вполне удалось. Несмотря на то, что kerioadmin использует Qt, элементы интерфейса выглядят архаичными и плохо согласуются с современным рабочим столом. Продукт поддерживает 12 языков, включая русский, но опцию для их смены найти не так-то просто, особенно человеку, не владеющему английским (впрочем, cреди администраторов их становится все меньше и меньше).&lt;br /&gt;
&lt;br /&gt;
Для входа в систему необходимо использовать имя пользователя и пароль, указанные на этапе первичной настройки. После этого откроется окно, представляющее все возможности сервера в виде древовидного списка. Итак, что же предлагает нам Kerio?&lt;br /&gt;
&lt;br /&gt;
Во-первых, стандартный набор служб: SMTP, POP3, IMAP, LDAP, HTTP со всеми безопасными разновидностями. «Самоподписанный» (self-signed) сертификат можно сгенерировать при помощи мастера. Во-вторых, виртуальные домены (способ поразному трактовать учетные записи в зависимости от того, к какому домену они принадлежат) с поддержкой служб каталогов Active Directory, Apple Open Directory и авторизацией через PAM/Kerberos, так что в этой области ''Kerio Mail Server'' вряд ли уступает своим закрытым конкурентам. Более того, KMS позволяет настроить разные методы авторизации для различных доменов: например, один домен авторизуется в одной службе каталогов, другой домен авторизуется непосредственно через PAM, и т.д. Помимо этого, предлагается контент-фильтр, включающий антивирус (интегрированный – от ''McAfee'' или внешний – ''AVG, NOD32, Sophos, Symantec'' и, конечно же, СlamAV. Выбор за вами, только имейте в виду, что в случае использования внешнего антивируса об обновлении баз придется заботиться самостоятельно), контроль вложений (в списке потенциально опасных расширений по умолчанию почему-то не активировано *.EXE) и антиспам. О последнем компоненте скажем чуть более подробно. Встроенный спам-фильтр KMS поддерживает систему рейтингов в стиле SpamAssassin, «черные» списки (как RBL, так и пользовательские; имеется возможность добавлять баллы в рейтинг вместо отказа в получении письма), «белый» список (по IP), технологии Caller ID и SPF, а также несколько примитивную систему пользовательских правил. Серые списки в явном виде отсутствуют – их заменяет механизм подавления спамерской активности, внедряющий дополнительные циклы ожидания в общении MTU/MTA. Судя по всему, спам-фильтр построен на базе SpamAssassin, что, на наш взгляд, вполне соответствует философии продуктов класса ''Kerio Mail Server'': «предоставлять стандартные решения, но в удобной форме». Тонкая настройка параметров фильтрации не предусмотрена, но с помощью имеющихся средств можно вполне надежно защититься от нежелательной корреспонденции.&lt;br /&gt;
&lt;br /&gt;
''Kerio Mail Server'' может не только выступать в роли MTA, принимая всю почту, адресованную вашему домену, но и просто периодически загружать сообщения из другого почтового ящика, поддерживаемого, например, вашим провайдером. Скачанные письма можно сортировать на основе заголовков. Поддерживаются протоколы POP3 и ETRN – последний используется не так уж часто, но лишняя функция, очевидно, не помешает.&lt;br /&gt;
&lt;br /&gt;
Отдельного упоминания заслуживают еще две функции – архивация писем (Archiving) и резервирование (Backup). KMS позволяет хранить всю корреспонденцию в структурированных архивах, так что всегда можно найти и «поднять» старое/забытое/удаленное письмо. Это будет полезно в организациях, в которых учет переписки имеет принципиальное значение (а где не имеет?).&lt;br /&gt;
&lt;br /&gt;
Резервирование также реализовано просто. По сути, достаточно указать каталог, в котором следует сохранять резервные копии (конечно, крайне желательно, чтобы он физически находился на отдельном компьютере или хотя бы диске), а набор предустановленных правил резервирования позаботится обо всем остальном. Поддерживаются как полные, так и дифференциальные резервные копии.&lt;br /&gt;
&lt;br /&gt;
Пожалуй, единственная область ''Kerio Mail Server'', выпадающая из сформулированного выше принципа «как у всех, но удобнее» – это ведение статистики и файлов журналов. И то, и другое откровенно слабо и практически не поддается настройке. Вероятно, сводная картина происходящего на сервере понравилась бы Большому Боссу, но она не несет достаточной информации для администратора, желающего произвести сколько-нибудь серьезный анализ. Журналы событий представлены в большом количестве, но содержащаяся в них информация сама по себе не может быть использована для оценки происходящего. Кнопка To Advanced Mode (см. рис.), казалось бы, должна помочь, но не тут-то было: она всего лишь дополняет отчет еще более бесполезным данными, такими, как суммарный размер почтовых сообщений, прошедших через сервер. Не хватает настроек детализации журналов, потому как на одну сессию с сервером в журнале отведена только одна строка со множеством параметров, по которой очень сложно отследить, что именно пытался сделать клиент.&lt;br /&gt;
&lt;br /&gt;
=== Выходим в Сеть ===&lt;br /&gt;
&lt;br /&gt;
Конечно, универсал, на роль которого претендует ''Kerio Mail Server'', не может обходиться без web-почты. Клиент Kerio Web Access являет собой слабую попытку сымитировать Outlook Web Access, предоставляемый Microsoft Exchange, но его внешний вид гораздо более приятен, чем у ''SquirrelMail'' в настройке по умолчанию. KWA, так же как и OWA, не любит Opera, но к счастью, поддерживает Mozilla. Порадовало также наличие календаря, как группового, так и персонального.&lt;br /&gt;
&lt;br /&gt;
Для поддержки web-почты не нужно конфигурировать Apache: web-сервер встроен в продукт, и его можно настроить на использование любого порта или группы портов. ''Kerio Web Access'' написан на PHP (KMS содержит свой собственный интерпретатор версии 4.3.11). Исходный код, за исключением модулей расширения, доступен в человеко-читаемой форме, что, вероятно, позволит (при необходимости) доработать KWA под нужды организации.&lt;br /&gt;
&lt;br /&gt;
=== Заключение ===&lt;br /&gt;
&lt;br /&gt;
Следует признать, что функциональность данного продукта (при сравнительно небольшой цене) впечатляет. Конечно, в нем нет ничего такого, что не смог бы настроить знающий администратор на базе стандартных средств, но зато и не надо тратить время на их изучение. ''Kerio Mail Server'' ориентирован на компании с гетерогенными сетями/серверами и средним (или даже небольшим) IT-бюджетом. Он также должен понравиться мигрантам с Windows, особенно тем, кто уже использовал продукты ''Kerio'' на этой платформе. [http://www.linuxformat.ru LXF]&lt;br /&gt;
&lt;br /&gt;
=== Вердикт Linux Format ===&lt;br /&gt;
&lt;br /&gt;
* Функциональность - 6/10&lt;br /&gt;
* Производительность - 6/10&lt;br /&gt;
* Простота использования - 8/10&lt;br /&gt;
* Цена - 6/10&lt;br /&gt;
&lt;br /&gt;
''Должен понравиться новичкам и мигрантом, но вы вряд ли захотите заменить им уже настроенный Sendmail или Postfix.''&lt;br /&gt;
&lt;br /&gt;
* '''Рейтинг''' - 6/10&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Kerio-1.png</id>
		<title>Файл:LXF90-Kerio-1.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Kerio-1.png"/>
				<updated>2008-03-20T20:06:37Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD:%D0%9A%D0%B0%D1%80%D1%82%D0%BE%D1%87%D0%BA%D0%B0_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B</id>
		<title>Шаблон:Карточка программы</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD:%D0%9A%D0%B0%D1%80%D1%82%D0%BE%D1%87%D0%BA%D0%B0_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B"/>
				<updated>2008-03-20T20:02:56Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{| class=&amp;quot;infobox&amp;quot; style=&amp;quot;float: right; width: 20em; font-size: 90%; line-height: 1.25em;&amp;quot; cellspacing=&amp;quot;5&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align: center; font-size: 130%; font-weight: bold;&amp;quot; | {{{name}}}&lt;br /&gt;
|-&lt;br /&gt;
{{#if: {{{logo|}}}|&lt;br /&gt;
{{!}} colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align: center;&amp;quot; {{!}} {{{logo|}}}}} &lt;br /&gt;
|-&lt;br /&gt;
{{#if: {{{screenshot|}}}&lt;br /&gt;
 | {{!}} colspan=&amp;quot;2&amp;quot; style=&amp;quot;padding: 1em 0; text-align: center;&amp;quot; {{!}} &amp;lt;div&amp;gt;{{{screenshot}}}&amp;lt;/div&amp;gt; {{#if: {{{caption|}}} | &amp;lt;div&amp;gt;{{{caption}}}&amp;lt;/div&amp;gt;}} }}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
|'''Тип'''&lt;br /&gt;
| {{{genre}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
{{#if: {{{developer|}}}{{{developers|}}}&lt;br /&gt;
 |&lt;br /&gt;
  {{!}} '''{{#if: {{{developers|}}} | Разработчики | Разработчик}}'''&lt;br /&gt;
  {{!}} {{{developers|{{{developer}}}}}}&lt;br /&gt;
}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
{{#if: {{{programming language|}}}{{{programming_language|}}}&lt;br /&gt;
 | &lt;br /&gt;
  {{!}} '''[[язык программирования|Написана на]]'''&lt;br /&gt;
  {{!}} {{{programming language|{{{programming_language}}}}}}&lt;br /&gt;
}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
|'''[[Операционная система|ОС]]'''&lt;br /&gt;
| {{{operating_system}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
{{#if: {{{latest_release_version|}}} | {{!}} '''Текущая версия''' {{!}}{{!}} {{{latest_release_version}}} {{#if: {{{latest_release_date|}}}| — {{{latest_release_date}}} }}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
{{#if: {{{latest_preview_version|}}} | {{!}} '''Текущая тестовая версия'''{{!}}{{!}} {{{latest_preview_version}}} {{#if: {{{latest_preview_date|}}}| — {{{latest_preview_date}}} }}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
|'''[[Лицензия]]'''&lt;br /&gt;
| {{{license}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
|'''[[Веб-сайт|Сайт]]'''&lt;br /&gt;
| {{{website}}}&lt;br /&gt;
|}&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD:%D0%9A%D0%B0%D1%80%D1%82%D0%BE%D1%87%D0%BA%D0%B0_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B</id>
		<title>Шаблон:Карточка программы</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD:%D0%9A%D0%B0%D1%80%D1%82%D0%BE%D1%87%D0%BA%D0%B0_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%8B"/>
				<updated>2008-03-20T19:57:40Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Новая: &amp;lt;includeonly&amp;gt;{| class=&amp;quot;infobox&amp;quot; style=&amp;quot;float: right; width: 20em; font-size: 90%; line-height: 1.25em;&amp;quot; cellspacing=&amp;quot;5&amp;quot; |- | colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align: center; font-size: 130%; font-...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{| class=&amp;quot;infobox&amp;quot; style=&amp;quot;float: right; width: 20em; font-size: 90%; line-height: 1.25em;&amp;quot; cellspacing=&amp;quot;5&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align: center; font-size: 130%; font-weight: bold;&amp;quot; | {{{name}}}&lt;br /&gt;
|-&lt;br /&gt;
{{#if: {{{logo|}}}|&lt;br /&gt;
{{!}} colspan=&amp;quot;2&amp;quot; style=&amp;quot;text-align: center;&amp;quot; {{!}} {{{logo|}}}}} &lt;br /&gt;
|-&lt;br /&gt;
{{#if: {{{screenshot|}}}&lt;br /&gt;
 | {{!}} colspan=&amp;quot;2&amp;quot; style=&amp;quot;padding: 1em 0; text-align: center;&amp;quot; {{!}} &amp;lt;div&amp;gt;{{{screenshot}}}&amp;lt;/div&amp;gt; {{#if: {{{caption|}}} | &amp;lt;div&amp;gt;{{{caption}}}&amp;lt;/div&amp;gt;}} }}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
|'''Тип'''&lt;br /&gt;
| {{{genre}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
{{#if: {{{developer|}}}{{{developers|}}}&lt;br /&gt;
 |&lt;br /&gt;
  {{!}} '''{{#if: {{{developers|}}} | Разработчики | Разработчик}}'''&lt;br /&gt;
  {{!}} {{{developers|{{{developer}}}}}}&lt;br /&gt;
}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
{{#if: {{{programming language|}}}{{{programming_language|}}}&lt;br /&gt;
 | &lt;br /&gt;
  {{!}} '''[[язык программирования|Написана на]]'''&lt;br /&gt;
  {{!}} {{{programming language|{{{programming_language}}}}}}&lt;br /&gt;
}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
|'''[[Операционная система|ОС]]'''&lt;br /&gt;
| {{{operating_system}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
{{#if: {{{latest_release_version|}}} | {{!}} '''Текущая версия''' {{!}}{{!}} {{{latest_release_version}}} {{#if: {{{latest_release_date|}}}| — {{{latest_release_date}}} }}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
{{#if: {{{latest_preview_version|}}} | {{!}} '''Текущая тестовая версия'''{{!}}{{!}} {{{latest_preview_version}}} {{#if: {{{latest_preview_date|}}}| — {{{latest_preview_date}}} }}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
|'''[[Лицензия]]'''&lt;br /&gt;
| {{{license}}}&lt;br /&gt;
|- style=&amp;quot;vertical-align: top;&amp;quot;&lt;br /&gt;
|'''[[Веб-сайт|Сайт]]'''&lt;br /&gt;
| {{{website}}}&lt;br /&gt;
|}{{#if: {{{screenshot|}}}||{{категория только в статьях|Статьи о программах без скриншотов}}}}&amp;lt;/includeonly&amp;gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/LXF90:SugarCRM</id>
		<title>LXF90:SugarCRM</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/LXF90:SugarCRM"/>
				<updated>2008-03-19T20:43:58Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Новая: == SugarCRM: Как его установить == ''{{oncolor||red|ЧАСТЬ 1}}: Вашему бизнесу не повредит автоматизация работы с зака...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== SugarCRM: Как его установить ==&lt;br /&gt;
''{{oncolor||red|ЧАСТЬ 1}}: Вашему бизнесу не повредит автоматизация работы с заказчиками. '''Марк Бэйн''' показывает, как приспособить для этих целей лучшее открытое ПО.''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
Добро пожаловать в новую серию! На первом уроке я покажу, как установить отличную CRM с открытым исходным кодом. А что такое CRM? Это Customer Relationship Management – системы управления взаимодействием с клиентами. Поняли? Для тех, кто не понял, Майкл Уайтхед-младший [Michael JR Whitehead] в книге ''“Implementing SugarCRM”'' определяет эти системы так: «CRM предназначены для хранения и обработки информации о ваших клиентах – не только о продажах, но и о дальнейших взаимоотношениях и поддержке. Системы обязаны давать хотя бы минимум информации о компаниях, с которыми вы работаете и о том персонале, с которым вы в них сотрудничаете».&lt;br /&gt;
&lt;br /&gt;
Между прочим, у вас почти наверняка все это есть. Мало того, что вы храните свои контакты в адресных книгах ''Thunderbird'', ''KMail'' или (содрогаюсь) ''Microsoft Outlook'', а счета в ''OpenOffice.org Calc'' или ''Microsoft Excel'' – небось еще и создали аж базы данных ''Base'' или ''Access'', и записываете туда все свои сделки. Все как будто прекрасно. Но дело в том, что все ваши коллеги проделывают те же операции со своим почтовым клиентом, электронными таблицами или базой данных. Вроде ничего плохого, разве что данные многократно дублируют-ся – и это бы не беда... пока не окажется, что данные не стыкуются.&lt;br /&gt;
&lt;br /&gt;
Представим себе следующую ситуацию. Пусть в число ваших заказчиков входит фирма Linux PCs Ltd. Вы записали ее почтовый адрес: Penguin House, Southwaite CA4 0AK. Но Фред справа уверяет, что правильный адрес – Penguin House, Carlisle CA4 0AK, а у Мэри слева он значится как Penguin House, Southwaite, Carlisle. Кто же прав? Настоящий адрес знает один Генри: фирма переехала, а он забыл всем про это сообщить.[[Изображение:LXF90-SugarCRM-1.png|thumb|SugarCRM управляется с номерами телефонов, номерами счетов и многим другим! Вам не по душе внешний вид? Его можно поменять.]]&lt;br /&gt;
&lt;br /&gt;
=== Разрулить весь бизнес ===&lt;br /&gt;
&lt;br /&gt;
Значит, CRM спасет вас от подобных ситуаций? Не только! Возможности CRM гораздо шире. Вот что вам предоставляется (опять цитирую Уайтхеда):&lt;br /&gt;
&lt;br /&gt;
* автоматизация работы персонала;&lt;br /&gt;
* мониторинг потенциальных возможностей;&lt;br /&gt;
* мониторинг канала продаж;&lt;br /&gt;
* определение групп сотрудников и территорий их деятельности;&lt;br /&gt;
* анализ основных источников прибыли;&lt;br /&gt;
* работа с каталогом продукции;&lt;br /&gt;
* создание выписок для клиентов;&lt;br /&gt;
* гибкая система формирования отчетов;&lt;br /&gt;
* мониторинг оказываемой клиентам технической поддержки;&lt;br /&gt;
* разработка план-графика выполняемых работ;&lt;br /&gt;
* хранение контактной информации организации;&lt;br /&gt;
* унификация взаимодействия с системой для различных пользователей;&lt;br /&gt;
* система контроля версий для документов.&lt;br /&gt;
&lt;br /&gt;
Хорошо, а какая с этого корысть? Во-первых, уменьшатся ваши издержки. Информация будет вводиться однократно, что исключает разночтения внутри вашего предприятия. Во-вторых, ваши сотрудники всегда будут в курсе событий на предприятии, и почувствуют себя полноправными их участниками, а не винтиками (это касается и персонала, и руководителей). Заказчики также будут довольны, имея дело с компетентными, хорошо осведомленными партнерами. Как следствие, возрастут продажи.&lt;br /&gt;
&lt;br /&gt;
Вы справедливо спросите: а кто я такой, чтобы об этом писать? Основное мое занятие – реализация и адаптация Clarify CRM; если у вас есть знакомые в фирме Vodafone, спросите их о проекте Cascade. Могут ли открытые CRM-системы достигать таких же результатов? Естественно, могут!&lt;br /&gt;
&lt;br /&gt;
=== Требования к серверу ===&lt;br /&gt;
&lt;br /&gt;
У ''SugarCRM'' нет отдельного пользовательского интерфейса – все делается через web-браузер. Это обеспечивает незавимость системы от платформы. Полагаю, вы предпочитаете Linux – так что радуйтесь: мы займемся платформой LAMP (''Linux-Apache-MySQL-PHP''). (Намек поняли? Именно это и надо установить на вашем сервере...)&lt;br /&gt;
&lt;br /&gt;
Начнем с сервера. Я установил ''SugarCRM'' под Debian на стареньком компьютере Patriot, и мне этого хватает. Но для предприятий рекомендую следующие спецификации:&lt;br /&gt;
&lt;br /&gt;
До 10 пользователей:&lt;br /&gt;
&lt;br /&gt;
* Жесткий диск IDE или SCSI емкостью 80–100 ГБ;&lt;br /&gt;
* 1 ГБ оперативной памяти с ECC (обнаружение и исправление ошибок);&lt;br /&gt;
* Процессор Athlon, Pentium 4, Xeon или Opteron с тактовой частотой не менее 2 ГГц.&lt;br /&gt;
&lt;br /&gt;
От 10 до 100 пользователей:&lt;br /&gt;
&lt;br /&gt;
* Жесткий диск SCSI емкостью 150 ГБ;&lt;br /&gt;
* 2–3 ГБ оперативной памяти с ECC;&lt;br /&gt;
* Процессор Xeon или Opteron с тактовой частотой не менее 2 ГГц.&lt;br /&gt;
&lt;br /&gt;
Более 100 пользователей:&lt;br /&gt;
&lt;br /&gt;
* Жесткий диск SCSI емкостью 300 ГБ;&lt;br /&gt;
* 4–8 ГБ оперативной памяти с ECC;&lt;br /&gt;
* Два процессора Xeon или Opteron с тактовой частотой не менее 2 ГГц.&lt;br /&gt;
&lt;br /&gt;
Все тот же Уайтхед, занимавшийся SugarCRM с 1999 г., также советует использовать:&lt;br /&gt;
&lt;br /&gt;
* Сеть Ethernet со скоростью 1 Гб;&lt;br /&gt;
* Источник бесперебойного питания (UPS) – бесценная штука, особенно если учесть, как они сейчас дешевеют;&lt;br /&gt;
* SUSE Linux. Хотя лично я предпочитаю использовать на моих серверах Debian (SUSE 10.1 у меня тоже стоит, на рабочей станции).&lt;br /&gt;
&lt;br /&gt;
=== Подготовка ===&lt;br /&gt;
&lt;br /&gt;
Linux, понятное дело, у вас есть; осталось добавить ''Apache 2'', ''MySQL'' и ''PHP''.&lt;br /&gt;
&lt;br /&gt;
''Apache 2'' устанавливается легко. В дистрибутиве Debian для этого нужно выполнить следующую команду&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install apache&lt;br /&gt;
&lt;br /&gt;
После установки убедитесь, что в конфигурационном файле web-сервера включена обработка ''PHP''-скриптов. Впрочем, в Debian это делается по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Установка MySQL ничуть не сложнее:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install mysql-server&lt;br /&gt;
&lt;br /&gt;
Все необходимые таблицы в базе данных ''SugarCRM'' позже создаст сама, а сейчас вам нужно лишь установить пароль для пользователя root. Подключитесь к базе и выполните следующий SQL-запрос:&lt;br /&gt;
&lt;br /&gt;
 update user&lt;br /&gt;
 set password=password(‘ваш_пароль’)&lt;br /&gt;
 where user = ‘root’;&lt;br /&gt;
&lt;br /&gt;
Пароль не забывайте: он потребуется при установке.&lt;br /&gt;
&lt;br /&gt;
Угадайте-ка, трудно ли установить PHP? Вот именно, нетрудно: процедура все та же, sudo '''APT-get install''', только на сей раз надо приписать '''php'''. Я уже упоминал, что файлы конфигурации Apache надо правильно настроить на обработку PHP-скриптов, но в Debian уже все сделано. Однако PHP все-таки придется настраивать. Поменяем системные переменные PHP в файле '''php.ini''', установив:&lt;br /&gt;
&lt;br /&gt;
* '''MEMORY_LIMIT в значение 64M.''' SugarCRM во время установки читает его неправильно и остается при значении по умолчанию: 8 МБ. Если не сменить эту переменную вручную, SugarCRM скорее всего упрется в лимит памяти и оставит вас с пустым экраном.&lt;br /&gt;
* '''MAX_EXECUTION_TIME в значение 90.''' Так мы предотвратим появление таймаутов при импорте больших объемов данных.&lt;br /&gt;
* '''MAX_INPUT_TIME в значение 300, а POST_MAX_SIZE в значение 25M.''' И то, и другое поможет загружать без ошибок файлы большого размера.&lt;br /&gt;
* '''Увеличенное значение SESSION.MAXLIFETIME.''' В течение этого времени SugarCRM ожидает ваших действий, а потом отключается (по умолчанию 1440 сек = 24 мин). Лучше взять его побольше, например, 3600 секунд (1 час). Нет ничего хуже, чем намучиться, составляя длинное почтовое сообщение, и тут же убедиться: приложение успело отсоединиться, и отправить почту нельзя.&lt;br /&gt;
&lt;br /&gt;
Теперь все готово для установки SugarCRM.&lt;br /&gt;
&lt;br /&gt;
=== Позаботимся о сотрудниках ===&lt;br /&gt;
&lt;br /&gt;
Итак, основная и самая трудная часть работы позади (а она показалась вам трудной?). Теперь загрузим архив программы с сайта http://www.sugarcrm.com, распакуем его в локальный каталог и запустим скрипт установки в браузере. Осталось только следовать инструкциям, появляющимся на экране.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим эти этапы поподробнее. Начнем со структуры каталогов ''SugarCRM''. После распаковки архива вы обнаружите новый каталог, с именем вроде '''SugarOS-Full-4.5.0g'''. Этот каталог нужно скопировать в корневую директорию web-сервера (где-то в '''htdocs'''). Для доступа к ''SugarCRM'' из вашего браузера в адресной строке наберите &amp;lt;nowiki&amp;gt;‘http://&amp;lt;имя_web-сервера&amp;gt;/SugarOS-Full-4.5.0g’&amp;lt;/nowiki&amp;gt;. Например, у меня путь был таким: &amp;lt;nowiki&amp;gt;‘http://hector/SugarOS-Full-4.5.0g’&amp;lt;/nowiki&amp;gt; (имя моего сервера – Hector).&lt;br /&gt;
&lt;br /&gt;
Однако это не самый удобный вариант URL. Сотрудники вашей фирмы не знают, что такое ''SugarCRM'' (им на это наплевать) – они просто хотят максимально облегчить свою работу. Пусть имя каталога говорит само за себя.&lt;br /&gt;
&lt;br /&gt;
Например, вы владелец издательства и решили выпускать новый журнал – назовем его хотя бы ''Linux Format'' (правда, красиво?). Тогда переименуем каталог в '''lxf'''. Пользователи будут набирать URL &amp;lt;nowiki&amp;gt;‘http://hector/lxf’&amp;lt;/nowiki&amp;gt;. Коротко и удобно, а действия ''SugarCRM'' никак не затрагивает. Каталог можно переименовать и попозже, но пользователей это в восторг уже не приведет. Лучше зайти в корневой каталог сервера и создать несколько символических ссылок на него, введя, допустим,&lt;br /&gt;
&lt;br /&gt;
  ln -s lxf linuxformat&lt;br /&gt;
  ln -s lxf magazine&lt;br /&gt;
&lt;br /&gt;
Доступ к программе даст любой из адресов &amp;lt;nowiki&amp;gt;‘http://hector/lxf’&amp;lt;/nowiki&amp;gt;, &amp;lt;nowiki&amp;gt;‘http://hector/linuxformat’&amp;lt;/nowiki&amp;gt; или &amp;lt;nowiki&amp;gt;‘http://hector/magazine’&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Мы почти готовы установить ''SugarCRM'', осталось только определить, кто по умолчанию будет владеть файлами ''SugarCRM'': это сильно повлияет на остаток процесса. Выясните, кто владелец вашего web-сервера по умолчанию, и назначьте его же владельцем каталога lxf. Например, в моем дистрибутиве Debian это ‘www-data’. Вообще-то я предусмотрел, что все файлы разрешают запись из группы, и добавил в группу себя, а сервер ''SugarCRM'' установил на моей рабочей станции: так я могу вносить все изменения прямо в файлы конфигурации.&lt;br /&gt;
&lt;br /&gt;
=== Наконец-то установка ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-SugarCRM-2.png|thumb|Увидав стартовое окно программы установки SugarCRM, считайте, что все почти готово.]]Вы, небось, уже открыли браузер и набрали URL вашего ''SugarCRM''. При правильной настройке вашего сервера ''Apache'' на поддержку скриптов PHP вы видите стартовое окно программы установки; если не видите, значит, нужно отредактировать файлы конфигурации ''Apache'' и перезапустить сервер. Пора жать кнопку “Start”.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 1 ====&lt;br /&gt;
На первом этапе установки перед вами окошко с лицензией продукта. Прочитав ее и установив соответствующую галочку, нажмите Next; вы попадете на самый полезный экран во всем процессе.&lt;br /&gt;
==== Шаг 2 ====&lt;br /&gt;
[[Изображение:LXF90-SugarCRM-3.png|thumb|Шаг 2 – самый важный: нужно вовремя подметить все ошибки и исправить их.]]Второй шаг – системная проверка. При этом выводится список всех компонентов, от которых зависит ''SugarCRM'', с указанием их статуса (существует в приемлемой версии; не существует, но без него можно обойтись; не существует, но обязателен). Вам придется установить отсутствующие компоненты и обновить устаревшие.&lt;br /&gt;
&lt;br /&gt;
Обычно не хватает модулей интерпретатора PHP. Что делать дальше, зависит от дистрибутива. В Debian недостающие модули легко установить через утилиту '''apt-get'''. Раздобыв все необходимые компоненты, нажмите кнопку Re-Check для повторной проверки.&lt;br /&gt;
&lt;br /&gt;
И помните, нельзя верить строке, извещающей о лимите оперативной памяти в PHP: даже если вы установили этот предел как 64 MБ, вы прочтете: ‘PHP Memory Limit &amp;gt;= 8M OK’.&lt;br /&gt;
==== Шаг 3 ====&lt;br /&gt;
Следующая задача – настройка базы данных MySQL. Фактически, настраивать ничего не придется – нужно лишь указать программе установки следующие параметры:&lt;br /&gt;
&lt;br /&gt;
* '''Host Name Имя хоста.''' По умолчанию ‘localhost’, и менять его незачем.&lt;br /&gt;
* '''DataBase Name Имя базы данных.''' По умолчанию ‘SugarCRM’. Лучше заменить чем-то более осмысленным, тем более, что переименование позволит иметь на сервере больше одной системы SugarCRM. Не забудьте установить флаг Create DataBase (Создать базу данных).&lt;br /&gt;
* '''Username/Password For SugarCRM Имя пользователя и пароль для SugarCRM;''' они необходимы для выполнения запросов к базе данных программы. По умолчанию ‘SugarCRM’, но опять же лучше заменить его более подходящим. Не забудьте отметить флаг Create User (Создать пользователя).&lt;br /&gt;
* '''Populate DataBase With Demo Data Занести в БД данные демонстрационного примера.''' Хотите – заносите и потренируйтесь с ними, хотите – нет. Лично мне это ни к чему.&lt;br /&gt;
* '''Privileged DataBase User Name Привилегированный пользователь БД.''' Обычно это ‘root’, но если вы создали другого пользователя с необходимыми привилегиями, можете использовать и его. Учтите, он должен иметь право управлять базой данных и создавать пользователей и таблицы (привилегии ‘dataBase’, ‘create user’ и ‘create tables’).&lt;br /&gt;
* '''Privileged DataBase User Password Пароль привилегированного пользователя.''' Вот почему мы устанавливали пароль для ‘root’ при первом запуске MySQL (помимо заботы о безопасности, разумеется).&lt;br /&gt;
&lt;br /&gt;
Все необходимые параметры указаны – нажимаем на кнопку Next. База данных будет создана позже, и если вы что-либо передумаете, можете вернуться к предыдущим шагам установки и внести изменения.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 4 ====&lt;br /&gt;
Произведем базовую настройку программы. Она включает установку URL-адреса для доступа к программе и задание пароля для администратора admin. URL на данном этапе не особо важен, и потом его можно будет поменять. Оставим тот, что по умолчанию. А вот пароль для admin понадобится при настройке системы и добавлении пользователей, так что запомните его хорошенько.&lt;br /&gt;
&lt;br /&gt;
Автоматическое обновление программы (флаг Enable Sugar Updates) может производить только администратор системы, и лучше этот флаг не устанавливать: у всех остальных пользователей он вызовет сообщение об ошибке. Флаг Advanced Site Security (дополнительные опции безопасности) то ли включает, то ли выключает их – неясно; поэтому я оставил его в состоянии Use Defaults (настройка по умолчанию).&lt;br /&gt;
&lt;br /&gt;
Как и раньше, нажатие кнопки Next не вносит необратимых изменений, и при желании вы сможете все переиграть.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 5 ====&lt;br /&gt;
Предпоследний этап. Делать ничего не надо, только проверить на экране, все ли данные указаны верно. Это ваш последний шанс изменить настройки. Готовы? Жмите кнопку Next.&lt;br /&gt;
&lt;br /&gt;
==== Шаг 6 ====&lt;br /&gt;
Сидите и наблюдайте за сборкой ''SugarCRM'' и созданием новой базы данных. Здесь бывают только 2 варианта ошибки. Первый – вы не установили пароль либо ввели его неправильно, и ''SugarCRM'' не может создать вам базу данных. Второй – неправильно указан объем памяти (см. раздел Подготовка). Придется повторить установку с самого начала, предварительно изменив строку ‘installer_locked =&amp;gt;true’ на ‘installer_locked =&amp;gt; false’ в файле '''config.php''', расположенном в каталоге программы.&lt;br /&gt;
&lt;br /&gt;
Но вы-то следовали инструкциям, и я надеюсь, что никаких проблем у вас не возникло, а ''SugarCRM'' успешно установлен. В следующем месяце мы займемся тонкой настройкой системы, включая введение привычной вашим пользователям терминологии. Информация о ''SugarCRM'' и ее применении приведена на www.sugarcrm.com. Это не обязательно касается свободной версии, но все равно любопытно, как она используется в большом бизнесе. До следующего раза! [http://www.linuxformat.ru LXF]&lt;br /&gt;
&lt;br /&gt;
=== Альтернативы SugarCRM ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-SugarCRM-4.png|thumb|Сравнение возможностей различных версий SugarCRM. www.sugarcrm.com/crm/products/]]Существует большое количество платных программ CRM. Среди них ''Microsoft CRM'' (http://www.microsoft.com/smallbusiness/products/mbs/crm/detail.mspx), ''Netsuite'' (www.netsuite.com) и ведущее ПО для управления контактами, ''SalesLogix'' (www.saleslogix.com).&lt;br /&gt;
&lt;br /&gt;
Почему же мы выбрали ''SugarCRM''? Ответ прост: открытый исходный код. На данный момент более миллиона пользователей по всему миру используют ''SugarCRM''. Разработку ведет SugarCRM Inc вместе с сообществом. Имеется большое количество расширений и дружелюбная поддержка на www.sugarcrm.com/forums. Если вы хотите установить такую систему у себя, бесплатная версия ''SugarCRM'' – лучший выбор.&lt;br /&gt;
&lt;br /&gt;
Доступны и платные версии программы, в том числе «арендуемые», т.е. пользователь платит за программу и за сервер. В платных версиях присутствуют дополнительные модули (например, прогноз продаж Sales Forecasting). Версия Professional обойдется вам в $40 за пользователя в месяц, а версия Enterprise, позволяющая работать с базой данных Oracle – в $75.&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-SugarCRM-1.png</id>
		<title>Файл:LXF90-SugarCRM-1.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-SugarCRM-1.png"/>
				<updated>2008-03-19T20:38:17Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-SugarCRM-2.png</id>
		<title>Файл:LXF90-SugarCRM-2.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-SugarCRM-2.png"/>
				<updated>2008-03-19T20:33:40Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-SugarCRM-3.png</id>
		<title>Файл:LXF90-SugarCRM-3.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-SugarCRM-3.png"/>
				<updated>2008-03-19T20:33:23Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-SugarCRM-4.png</id>
		<title>Файл:LXF90-SugarCRM-4.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-SugarCRM-4.png"/>
				<updated>2008-03-19T20:32:13Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-4.png</id>
		<title>Файл:LXF90-LaTeX-4.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-4.png"/>
				<updated>2008-03-18T19:41:49Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-6.png</id>
		<title>Файл:LXF90-LaTeX-6.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-6.png"/>
				<updated>2008-03-18T19:41:39Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-3.png</id>
		<title>Файл:LXF90-LaTeX-3.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-3.png"/>
				<updated>2008-03-18T19:41:30Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-5.png</id>
		<title>Файл:LXF90-LaTeX-5.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-5.png"/>
				<updated>2008-03-18T19:41:24Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-1.png</id>
		<title>Файл:LXF90-LaTeX-1.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-1.png"/>
				<updated>2008-03-18T19:41:02Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/LXF90:LaTeX</id>
		<title>LXF90:LaTeX</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/LXF90:LaTeX"/>
				<updated>2008-03-18T19:39:51Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Новая: == Путеводитель по классам LaTeX == ''{{oncolor||red|ЧАСТЬ 7}} Подобно Золушке, ставшей принцессой, документ LaTeX мож...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Путеводитель по классам LaTeX ==&lt;br /&gt;
''{{oncolor||red|ЧАСТЬ 7}} Подобно Золушке, ставшей принцессой, документ LaTeX может несколько раз сменить свой класс за время существования. Многообразие классов LaTeX способно смутить любого – но '''Евгений Балдин''' предлагает их полную классификацию.''&lt;br /&gt;
&lt;br /&gt;
Класс документа – это первое, что требуется указать при наборе. В то же время первое вовсе не значит важное. С заключительным выбором класса почти всегда можно повременить до окончания основного набора. С другой стороны, выбирать всё равно когда-нибудь придётся, так что нелишне знать, что может нам предложить LaTeX.&lt;br /&gt;
&lt;br /&gt;
== {{oncolor||red|Зачем нужны эти классы?}} ==&lt;br /&gt;
&lt;br /&gt;
Класс документа выбирается с помощью команды {{oncolor||red|documentclass}}. Её нужно и можно выполнить ровно один раз в самом начале документа:&lt;br /&gt;
&lt;br /&gt;
 \documentclass[a4paper,12pt]{article}&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-LaTeX-1.png|thumb|(Рис. 1) Класс papertex - пример от автора класса Ignacio Liopis]]В качестве обязательного аргумента указывается имя класса, которому через запятую передаются необязательные параметры. Класс определяется в файле с расширением '''.cls'''. В дистрибутиве ''LaTeX TeX Live 2005'' присутствует 175 уникальных файлов с подобным расширением. Естественно, это далеко не все существующие на белом свете классы, тем более, что никто не мешает вам создать свой личный класс. Но для начала лучше все же воспользоваться одним из имеющихся.&lt;br /&gt;
&lt;br /&gt;
Класс определяет вид и структуру документа. Класс – это база, которую можно править с помощью подключаемых стилевых файлов. В классе задаётся геометрия страницы и определяются команды секционирования. Сам по себе класс может быть как просто небольшой модификацией уже имеющегося, так и принципиально новой реализацией представления печатного или электронного TeXнического слова. В качестве примера последнего можно привести молодой (2007 год) пока пакет {{oncolor||red|papertex}}, который позволяет применять ''LaTeX'' в деле вёрстки газет, то есть для того, для чего ''LaTeX'' в проекте вовсе не предназначался. Сам пакет можно найти на любом CTAN-архиве в директории '''{CTAN}/macros/LaTeX/contrib/papertex/'''.&lt;br /&gt;
&lt;br /&gt;
== {{oncolor||red|Классовая база}} ==&lt;br /&gt;
&lt;br /&gt;
Исторически сложилось так, что LaTeX начался с 6 классов: {{oncolor||red|article}} (статья), {{oncolor||red|book}} (книга), {{oncolor||red|report}} (отчёт), {{oncolor||red|proc}} (доклад), {{oncolor||red|letter}} (письмо) и {{oncolor||red|slides}} (слайды).&lt;br /&gt;
&lt;br /&gt;
По идее, статьи следовало набирать в {{oncolor||red|article}}. В этом классе определены команды секционирования вплоть до {{oncolor||red|section}} (раздел). Одним из желательных элементов оформления является предисловие (окружение {{oncolor||red|abstract}}). В классе {{oncolor||red|book}} присутствует расширенный набор команд секционирования, в который добавлена команда {{oncolor||red|chapter}} (глава). Также в классе {{oncolor||red|book}} присутствует базовый набор команд для оформления титульного листа, предисловия и оглавления. Класс для создания отчёта {{oncolor||red|report}} является упрощённой версией класса {{oncolor||red|book}}. Отчёты – те же книги, только читают их по необходимости, а не по желанию. Класс {{oncolor||red|proc}}, предназначенный для создания тезисов докладов, в свою очередь является модификацией класса {{oncolor||red|article}}, причём основное отличие состоит в обязательной двухколоночной печати. Для написания писем был создан класс {{oncolor||red|letter}}. Набор команд в этом классе существенно отличается от уже перечисленных, в частности, для писем нет нужды в командах секционирования. Класс {{oncolor||red|slides}} – простой и быстрый способ сделать презентацию. С помощью этого класса не удастся создать пёстрого фона и головокружительных эффектов смены слайдов, зато он позволяет сосредоточиться на основном – на тексте.&lt;br /&gt;
&lt;br /&gt;
Особняком от этих классов стоит класс {{oncolor||red|minimal}}, который является «болванкой» для создания и тестирования новых классов и идей. В классе {{oncolor||red|minimal}} не определено никаких специальных команд – минимум есть минимум. В качестве побочного эффекта документ, выбирающий этот класс, транслируется ''LaTeX'' значительно быстрее.&lt;br /&gt;
&lt;br /&gt;
С этих классов всё начиналось, но на них ничего не закончилось. Следует понимать, что базовые классы далеко не так хороши, как хотелось бы. После трансляции текста сразу возникает желание взять в руки «электронный надфиль» и пройтись по настройкам класса. Это цена за то, что перечисленные классы являются базовыми. На них ссылается и их модифицирует множество других классов и пакетов, поэтому их развитие было заморожено. Для начального набора сгодится и это, но для конечной вёрстки лучше подобрать что-то более подходящее, или придётся серьёзно модифицировать значения по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Часто набор необязательных параметров для стандартных классах используется и в других классах, например, в целях совместимости. Некоторые из полезных опций перечислены ниже:&lt;br /&gt;
* '''10pt|11pt|12pt''' – установка базового размера шрифта. Обычно этих трёх значений хватает.&lt;br /&gt;
* '''a4paper''' – установка размера листа бумаги. Следует использовать всегда, так как по умолчанию ''LaTeX'' использует размер листа {{oncolor||red|letter}}.&lt;br /&gt;
* '''draft''' – режим черновой печати для «отлавливания» проблем вёрстки. В этом режиме не внедряются картинки (вместо них вставляются прямоугольники нужного размера) и отмечаются строчки, где алгоритм разбиения абзаца на строки даёт осечку.&lt;br /&gt;
* '''oneside|twoside''' – форматирование документа для односторонней и двухсторонней печати, соответственно.&lt;br /&gt;
* '''twocolumn''' – печать в две колонки.&lt;br /&gt;
&lt;br /&gt;
== {{oncolor||red|Классификация}} ==&lt;br /&gt;
                                                                              &lt;br /&gt;
Сразу предупрежу: число классов постоянно растёт, поэтому не следует думать, что все имеющиеся варианты исчерпываются классами, перечисленными ниже.&lt;br /&gt;
                                                                              &lt;br /&gt;
=== Модификации и улучшения базы ===&lt;br /&gt;
&lt;br /&gt;
Стандартные классы не нравятся всем, и всякий старается их улучшить. Кто-то убирает какой-то конкретный недостаток, как это сделано в наборе классов {{oncolor||red|extsizes}} ({{oncolor||red|extarticle, extbook, extletter, extproc, extreport}}), которые отличаются от стандартных только возможностью указать базовый размер шрифта, отличный от обычного {{oncolor||red|10-12pt}}. Есть наборы классов, которые делались с какой-то определённой целью. Примером такого подхода являются классы от AMS ({{oncolor||red|amsart, amsbook, amsproc}}), которые используются для материалов, предназначенных для публикации в журналах Американского математического сообщества. Классы из набора {{oncolor||red|ntgclass}} представляют из себя «героическую» попытку немецкоговорящих голландцев сделать то же, что и в стандарте, но существенно разными способами.&lt;br /&gt;
&lt;br /&gt;
=== KOMA-Script ===&lt;br /&gt;
&lt;br /&gt;
В последнее время всё больше внимания обращает на себя набор классов KOMA-script. В этот раз хорошо постарались немцы. Следует учитывать, что европейские традиции полиграфии (в основном французские), всё-таки ближе к нам, чем американские, на которые традиционно ориентировалось ''LaTeX''-сообщество. Для статей предполагается использовать {{oncolor||red|scrartcl}}, для книг {{oncolor||red|scrbook}}, для писем {{oncolor||red|scrlttr2}}, а для отчётов {{oncolor||red|scrreprt}}.&lt;br /&gt;
&lt;br /&gt;
В отличие от стандарта, классы из KOMA-script позволяют использовать базовые размеры шрифта в 9pt, 14pt и 17pt. Огромные поля, имеющие место в стандартных классах, в классах KOMA-script значительно уменьшены. Претерпели изменения и другие элементы. Если оформление по умолчанию не кажется адекватным, то KOMA-script предоставляет обширный набор высокоуровневых настроек. Подробная документация на более чем двухстах страницах «The KOMA-Script bundle» ('''scrguien.pdf''') позволяет подстроить все необходимые параметры.&lt;br /&gt;
&lt;br /&gt;
=== NCC ===&lt;br /&gt;
&lt;br /&gt;
Ещё один вариант замены стандартных классов – это использование пакета NCC. Очень подробно об этом пакете написано в замечательной книге от создателя NCC Александра И. Роженко: ''«Искусство верстки в LaTeX’е»'', 2005 (ISBN 5-901548-25-6).&lt;br /&gt;
&lt;br /&gt;
Для использования следует загрузить класс {{oncolor||red|ncc}} и передать ему желаемый стиль оформления в качестве параметра: {{oncolor||red|article}} (статья – используется по умолчанию), {{oncolor||red|preprint}} (препринт), {{oncolor||red|book}} (монография) или {{oncolor||red|report}} (отчёт). Дальнейшие подробности об использовании этого класса можно почерпнуть в краткой инструкции к пакету: '''nccLaTeX.pdf'''.&lt;br /&gt;
&lt;br /&gt;
=== Поддерживаем стандарты ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-LaTeX-2.png|thumb|(Рис. 2) Страница документации к eskdx]]Стандарт подразумевает наличие подробного описания, которое и является его сущностью. То, что написано на бумаге в виде набора непротиворечивых правил, может быть переведено на язык машины. Далее можно забыть про эти правила, так как помнить все нюансы – работа для машины5 '''(Рис. 2)'''.&lt;br /&gt;
&lt;br /&gt;
Константин Кориков создал и активно поддерживает пакет ''eskdx'', который представляет из себя набор классов и стилей, предназначенный для вёрстки документации в соответствии с требованиями «Единой системы конструкторской документации». Основу коллекции составляют три класса: {{oncolor||red|eskdtext}} (для текстовой документации), {{oncolor||red|eskdbtab}} (для чертежей и схем) и {{oncolor||red|eskdgraph}} (для документов, разбитых на графы). Внятная документация на русском ('''eskdx.pdf''') приятно дополняет картину. Пакет можно найти на CTAN в директории '''{CTAN}/macros/LaTeX/contrib/eskdx/''', а его домашняя страничка расположена по адресу: http://lostclus.linux.kiev.ua/eskdx/.&lt;br /&gt;
&lt;br /&gt;
''eskdx'' – относительно молодой пакет. Ранее аналогичная попытка была предпринята Вячеславом Фёдоровым, в результате которой на свет появился пакет eskd (без «x» на конце). В отличии от класса Константина Корикова, класс {{oncolor||red|eskd.cls}} требует обязательной установки шрифтов из коллекции {{oncolor||red|pscyr}}.&lt;br /&gt;
&lt;br /&gt;
Стандарт для написания документов, описывающих стандарты. Что может быть ещё более стандартным? Класс {{oncolor||red|isov2.cls}} из пакета iso является стандартом для стандартов. Документация к пакету '''isoman.pdf''' подробно описывает все технические тонкости в деле подготовки документов по стандартам ISO. Аналогично, для создания документации ISO 10303 есть свой пакет iso10303.&lt;br /&gt;
&lt;br /&gt;
=== Пишем письма ===&lt;br /&gt;
&lt;br /&gt;
Класс {{oncolor||red|letter}} является стандартным для ''LaTeX'' и, как следствие, никто им не пользуется. Часто стандарт для написания писем создаётся автором самостоятельно. Так, например, любит делать Кнут. Это очень неплохо работает в силу того, что структура письма не слишком сложна. Как следствие, в ''LaTeX'' имеется огромное число альтернатив для {{oncolor||red|letter}}.&lt;br /&gt;
&lt;br /&gt;
С точки зрения английского FAQ по ''LaTeX'' (http://www.tex.ac.uk/faq) класс {{oncolor||red|newlfm}} является наиболее продвинутым. {{oncolor||red|lfm}} расшифровывается как {{oncolor||red|letter}} (письмо), {{oncolor||red|fax}} (факс) и {{oncolor||red|memorandum}} (служебная записка). Документация представляет из себя текстовый README и набор примеров использования.&lt;br /&gt;
&lt;br /&gt;
Хорошо документированный класс {{oncolor||red|akletter}} также является хорошим шаблоном для старта. Документация '''lettereng.pdf''', кроме краткой инструкции, также включает и формальное описание структуры письма.&lt;br /&gt;
&lt;br /&gt;
Упомянутый выше пакет KOMA-script предоставляет прекрасную замену стандартному классу {{oncolor||red|letter}} в виде {{oncolor||red|scrlttr2}}. Набор классов {{oncolor||red|ntgclass}} также предоставляет свой вариант в виде класса {{oncolor||red|brief}}.&lt;br /&gt;
&lt;br /&gt;
Кроме более-менее общих решений, полно и частных. Например, для внутренней переписки университета города Падуя есть специальный пакет {{oncolor||red|cdpbundl}}, содержащий целых три класса.&lt;br /&gt;
&lt;br /&gt;
=== Верстаем книги ===&lt;br /&gt;
&lt;br /&gt;
Написание книги – это очень долгий процесс, и первоначальную «набивку» текста можно начать со стандартного класса {{oncolor||red|book}}. С другой стороны, структура книги может быть очень сложной, и правильный выбор базового класса позволит несколько облегчить процесс созидания.&lt;br /&gt;
&lt;br /&gt;
В качестве улучшенного стандартного класса {{oncolor||red|book}} можно использовать класс {{oncolor||red|octavo}}. Класс {{oncolor||red|scrbook}} из KOMA-script также является хорошей альтернативой для {{oncolor||red|book}}. Структура и основные команды копируют стандартный класс. Значения же параметров по умолчанию более адекватны для европейской полиграфии.&lt;br /&gt;
&lt;br /&gt;
Описание класса {{oncolor||red|memoir}} ('''memman.pdf''') представляет из себя книгу о создании книги, превышающую по объёму триста страниц. Там есть всё, начиная от формальной структуры печатной книги, советов по оформлению электронных копий, и заканчивая собственно описанием класса. Все элементы структуры и управляющие размеры показаны в виде рисунков и схем. Класс не является надстройкой над чем-либо – это произведение искусства, созданное с нуля. Документацию следует пролистать хотя бы просто для ознакомления. Класс развивается до сих пор. Новые возможности описываются в дополнении к основной документации ('''memmanadd.pdf'''), и на текущий момент дополнение почти достигло объёма в сто страниц.&lt;br /&gt;
&lt;br /&gt;
Если не требуется написать книгу, а нужно распечатать мегабайтный текст на дешёвеньком принтере в режиме экономии тонера, то для этого дела вполне может подойти класс {{oncolor||red|sffms}} – простенько и строки через два интервала.&lt;br /&gt;
&lt;br /&gt;
=== Создаём отчёты ===&lt;br /&gt;
&lt;br /&gt;
Отчёт – не книга, но и здесь есть свои правила и структура. Для начала можно воспользоваться {{oncolor||red|scrreprt}} из KOMA-script, как замена стандартному классу {{oncolor||red|report}}.&lt;br /&gt;
&lt;br /&gt;
Инженер-электронщик Эли Биллауэр [Eli Billauer] сделал ''LaTeX''-класс для бумаг в HiTech-стиле и назвал его, соответственно, hitec. Простенько и со вкусом. Есть, естественно, и частные решения. Хочется заключить контракт с американским правительством – стандартная форма 298, обеспечиваемая классом {{oncolor||red|sffms}}, будет вполне кстати. Класс {{oncolor||red|manual}} из пакета {{oncolor||red|nassflow}} даст возможность пообщаться со структурой под названием «Center for the Automation of Weapon and Command Systems, Royal Netherlands Navy» [Центр автоматизации вооружения и командных систем Королевских ВМФ, Нидерланды].&lt;br /&gt;
&lt;br /&gt;
=== Делаем презентации ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-LaTeX-3.png|thumb|(Рис. 3) prosper в действии]]В начале предполагалось, что цель презентации состоит в распространении нужной информации от одного человека ко многим. Поэтому во главу угла ставился текст, а «украшательства» сводились к простой рамке. Стандартные классы {{oncolor||red|seminar}} и {{oncolor||red|sides}} вполне годились для этого.&lt;br /&gt;
&lt;br /&gt;
Но время суровых докладчиков прошло, и «рюшечки» вышли на первый план. ''LaTeX'' может предоставить и «рюшечки», но лучше всётаки помнить о смысле.&lt;br /&gt;
&lt;br /&gt;
Класс {{oncolor||red|prosper}} создан как улучшенный {{oncolor||red|seminar}} и поддерживает не только оверлеи, гиперссылки и шаблоны оформления, но и «стандартный» набор динамических эффектов доступных через формат pdf. Вспомогательный класс {{oncolor||red|ppr-prv}} позволяет создать печатную версию электронных слайдов класса prosper.&lt;br /&gt;
&lt;br /&gt;
В пакет {{oncolor||red|texpower}} входит класс {{oncolor||red|powersem}}, который, по сути дела, просто загружает {{oncolor||red|slides}}, а всю работу по созданию презентации выполняет стиль {{oncolor||red|texpower}}. Возможности этого пакета сравнимы с {{oncolor||red|prosper}} – просто он немного другой.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-LaTeX-4.png|thumb|(Рис. 4) beamer – справится даже школьник. Изготовлено учеником 11 класса А.Ф. Зайковым самостоятельно. На ошибки не фыркаем! Школьник всё-таки.]]В последнее время в деле создания презентации всё популярнее и популярнее становится относительно молодой, но довольно мощный класс {{oncolor||red|beamer}}. Активная поддержка сообщества при создании этого пакета позволила автору beamer Тилу Тантау (Till Tantau) собрать в одном месте немало тем для слайдов. Ключевой особенностью этих тем является разнообразие. Наличие широкого выбора стандартных тем позволяет быстро выбрать обрамление для презентации. Более чем 200 страниц документации ускоряют решение любой возникшей проблемы.&lt;br /&gt;
&lt;br /&gt;
Для создания презентаций можно настроить даже WYSIWYM-редактор ''LyX''. Для этого следует воспользоваться ещё одним достаточно молодым, но уже вполне функциональным классом {{oncolor||red|powerdot}}, в комплекте с которым идут настройки для ''LyX''.&lt;br /&gt;
&lt;br /&gt;
Класс {{oncolor||red|talk}}, в отличие от упомянутых выше пакетов, позволяет пользователю определить более одного стиля слайдов для презентации. Резкая смена стиля во время доклада – иногда бывает нужно и такое.&lt;br /&gt;
&lt;br /&gt;
Для создания настенного постера в первом приближении можно воспользоваться пакетом {{oncolor||red|a0poster}}, который позволяет работать с большими форматами бумаги. Канонического класса, который бы решал все проблемы при изготовлении постера, в ''LaTeX'' на текущий момент не существует. Возможно, ближе всего к идеалу подошёл класс {{oncolor||red|sciposter}} из одноимённого пакета.&lt;br /&gt;
&lt;br /&gt;
=== Защищаем диссертации ===&lt;br /&gt;
&lt;br /&gt;
Раньше всюду были курсовые и дипломные работы, а теперь, куда ни плюнь, везде диссертации. Каждый уважающий, не сильно уважающий и вообще не уважающий себя университет имеет свой уникальный стиль оформления диссертации. Если хочется написать свой класс, то в качестве отправной точки можно выбрать {{oncolor||red|ucthesis}} от Калифорнийского университета (UC Berkeley).&lt;br /&gt;
&lt;br /&gt;
Станислав Кручинин озадачился судьбами русскоговорящих диссертантов и создал класс {{oncolor||red|disser}}. Пакет с одноимённым названием можно взять на CTAN в директории '''{CTAN}/macros/LaTeX/contrib/disser'''. Следует учесть, что пользовательская документация на текущий момент отсутствует. С другой стороны, диссертанты, по идее, люди неглупые и разберутся в имеющихся примерах.&lt;br /&gt;
&lt;br /&gt;
=== Организуем резюме ===&lt;br /&gt;
&lt;br /&gt;
Написание резюме или curriculum vitae – довольно популярный вид деятельности в современном мире. Для резюме нет общепринятого стандарта, но некоторые указания существуют.&lt;br /&gt;
&lt;br /&gt;
Европейская комиссия рекомендует определённый формат для составления резюме, и этот формат полностью реализуется с помощью класса {{oncolor||red|europecv}}. Класс {{oncolor||red|vita}} представляет собой конструктор для создания резюме. Несмотря на отсутствие документации, разобраться с ним по имеющимся примерам для IT-специалиста и певца не составит сложности. Класс {{oncolor||red|curve}}, напротив, обладает качественной документацией. Механизм рубрик позволяет классу curve поддерживать несколько резюме разной направленности и легко переключаться между ними. Современный класс {{oncolor||red|morderncv}} рекомендуется как гибкое и простое средство создания резюме как современного вида, так и классической формы. Пакет можно взять на CTAN в директории '''{CTAN}/macros/LaTeX/contrib/moderncv'''.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-LaTeX-5.png|thumb| (Рис. 5) Класс moderncv.]]Следует отметить, что классы определяют многое, но далеко не всё. Поэтому после выбора класса можно подключить стили, которые серьёзно поменяют внешний вид документа. Стиль {{oncolor||red|currvita}} позволяет создавать резюме в окружении стандартных классов.&lt;br /&gt;
&lt;br /&gt;
=== Журнальные и конференционные классы ===&lt;br /&gt;
&lt;br /&gt;
Каждый серьёзный научный журнал и крупная конференция имеет свой ''LaTeX-класс''. Обычно этот класс лежит где-то на официальном сайте, например, журналы, издаваемые издательством МАИК «Наука/Интерпериодика», должны следовать правилам, выложенным здесь: http://www.maik.ru/pub/tex/. Но довольно много журнальных классов можно найти в стандартном дистрибутиве LaTeX. Например, класс {{oncolor||red|asaetr}} используется в American Society for Agricultural Engineers (ASAE). Maple Technical Newsletter можно создавать с помощью класса {{oncolor||red|mtn}}. Классом {{oncolor||red|jpsj2}} отметились японцы. Из русскоязычных журналов замечен только «Сибирский журнал вычислительной математики» – класс {{oncolor||red|sibjnm}}.&lt;br /&gt;
&lt;br /&gt;
Следует отметить класс {{oncolor||red|elsart}}, обязательный для подготовки журнальных публикаций в издательстве Elsevier. Класс {{oncolor||red|nature}} позволит подготовить pdf-файл для журнала Nature. Часто при создании публикаций для журналов или конференций используются небольшие модификации класса {{oncolor||red|revtex4}}.&lt;br /&gt;
&lt;br /&gt;
Для объединения разных документов в один, например, для оформления трудов конференции, может пригодиться класс {{oncolor||red|combine}}.&lt;br /&gt;
&lt;br /&gt;
=== Всякая всячина ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-LaTeX-6.png|thumb|(Рис. 6) Что-то определённо тибетское – класс pecha.]]Далеко не все классы подчиняются уже перечисленной классификации. За рамки темы вышли классы для составления календарей, обложек для CD ({{oncolor||red|cd}}), вопросников ({{oncolor||red|qcm}}), объявлений о занятиях ({{oncolor||red|assignment}}), концертных программок ({{oncolor||red|ConcProg}}), программ курсов ({{oncolor||red|courseoutline}} и {{oncolor||red|coursepaper}}), рабочего журнала для биологов ({{oncolor||red|labbook}}), пьес ({{oncolor||red|stage}}), тибетских карточек ({{oncolor||red|pecha}}), карточек для запоминания иностранных слов ({{oncolor||red|flashcards}}), и для многого другого. Старые и давно не поддерживаемые классы могут не собраться в новом окружении, но исходные тексты доступны, так что их всегда можно довести до необходимой кондиции.&lt;br /&gt;
&lt;br /&gt;
== {{oncolor||red|Заключение}} ==&lt;br /&gt;
&lt;br /&gt;
Классов существует много – места в статье мало. Малая толика из упомянутых классов будет рассмотрена в последующих статьях цикла. Это не является проблемой, так как в чём-чём, а в отсутствии документации к пакетам ''LaTeX'' обвинить невозможно – ну, почти. [http://www.linuxformat.ru LXF]&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-2.png</id>
		<title>Файл:LXF90-LaTeX-2.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-LaTeX-2.png"/>
				<updated>2008-03-18T19:39:37Z</updated>
		
		<summary type="html">&lt;p&gt;Human: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/LXF90:Unix_API</id>
		<title>LXF90:Unix API</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/LXF90:Unix_API"/>
				<updated>2008-03-16T17:29:45Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Новая: == Консольный ввод/вывод == ''{{oncolor||green|ЧАСТЬ 10}} Привыкли считать консольные приложения лишенными польз...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Консольный ввод/вывод ==&lt;br /&gt;
''{{oncolor||green|ЧАСТЬ 10}} Привыкли считать консольные приложения лишенными пользовательского интерфейса? Напрасно – старый добрый терминал способен на многое. На что именно – расскажет '''Андрей Боровский'''.''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
''Real computer scientists despise the idea of actual hardware. Hardware has limitations, software doesn’t. It’s a real shame that Turing machines are so poor at I/O.'' (Из программистского фольклора)&lt;br /&gt;
&lt;br /&gt;
Каждому, кто приступает к изучению программирования для Unix, консольный ввод/вывод представляется простым делом. Для создания графических программ необходимо сначала изучить язык программирования, а затем – один из интерфейсов программирования графики. Для создания консольных программ достаточно изучить язык программирования. Если вы не шли к изучению программирования окольными путями, то ваши первые программы наверняка были консольными. Однако интерфейс консоли Unix обладает гораздо большим числом возможностей, чем кажется на первый взгляд. О некоторых дополнительных возможностях работы с консолью мы и поговорим сегодня. Богатство функций работы с консолью в Unix объясняется тем, что у Unix долгая история. Когда-то терминалы были настоящими устройствами (в некоторых областях человеческой деятельности такие устройства применяются и сейчас), подключенными к компьютеру через последовательный порт. Часто терминал и компьютер были отделены друг от друга прослойкой в виде пары модемов и телефонной линии. Последовательный порт и модем считались неотъемлемой частью терминала, и интерфейс управления ими стал частью интерфейса управления терминалом. Кроме того, такие устройства, как, например, принтеры, тоже считаются терминалами Unix. Если в графическом программировании принтер считается устройством ввода/вывода данных, подобным графическому дисплею, то вполне логично, что в консольном программировании принтер рассматривается как терминал. Таким образом, с точки зрения Unix терминалами считается множество устройств, которые работают совершенно по-разному. Неудивительно, что для управления всем этим многообразием устройств потребовался сложный интерфейс. И хотя вы вряд ли подключаетесь к своему компьютеру с помощью модема (у вас, возможно и модема-то уже нет), а для вывода документа на печать вы, скорее всего, используете фильтр PostScript, некоторые возможности управления терминалом, появившиеся в незапамятные времена, могут пригодиться и вашим программам.&lt;br /&gt;
&lt;br /&gt;
=== Предотвращение перенаправления вывода ===&lt;br /&gt;
&lt;br /&gt;
Вы, конечно, знаете, что в Unix вывод консольной программы, предназначенный монитору, может быть перенаправлен в файл или в поток ввода другой программы. Часто это бывает не только полезно, но даже необходимо. Теперь можете проверить свою сообразительность. Отодвиньте эту статью на десять секунд и подумайте, в каких случаях программа не должна допускать перенаправление своего вывода? Самый простой пример – интерактивная консольная программа. Интерактивные программы выводят данные небольшими порциями, после чего останавливаются в ожидании реакции пользователя. Примером такой программы может служить клиент SSH. Если пользо- ватель пытается перенаправить вывод интерактивной программы, значит, он, скорее всего, просто не понял, как работать с вашей программой. Желательно предотвратить бессмысленное действие и сообщить пользователю об этом. Рассмотрим сначала простейший пример программы, которая не позволяет перенаправить свой вывод на устройство, не являющееся терминалом (текст этой программы вы найдете на диске, в файле '''noredirect.c''').&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;unistd.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 int main (int argc, char ** argv)&lt;br /&gt;
 {&lt;br /&gt;
   char * errstr = “I will not redirect my output!\n”;&lt;br /&gt;
   if (!isatty(fileno(stdout))) {&lt;br /&gt;
     write(2, errstr, strlen(errstr));&lt;br /&gt;
      return EXIT_FAILURE;&lt;br /&gt;
    }&lt;br /&gt;
    printf (“Hello!\n”);&lt;br /&gt;
    return EXIT_SUCCESS;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Функция {{oncolor||red|isatty(3)}} позволяет программе узнать, является ли предоставленное ей устройство ввода/вывода терминалом. Аргументом {{oncolor||red|isatty()}} должен быть дескриптор файла устройства, который мы получаем из переменной stdout, пользуясь функцией {{oncolor||red|fileno(3)}}. Функция {{oncolor||red|isatty()}} возвращает единицу, если переданный ей дескриптор соответствует терминалу, и 0 – в противном случае. Программа noredirect напечатает строку “Hello!”, только если у нее есть доступ к терминалу. Если же вы скомандуете&lt;br /&gt;
&lt;br /&gt;
 noredirect &amp;gt; file&lt;br /&gt;
&lt;br /&gt;
на экране появится гневное сообщение, а файл '''file''' окажется пустым. Впрочем, возможно, вы не всегда будете столь строгим по отношению к пользователю. Вам может потребоваться частично запретить перенаправление для выделенных мест программы. В этом случае можно воспользоваться трюком, который показан в программе ''noredirect2'' ('''noredirect2.c''' на диске).&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;fcntl.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;string.h&amp;gt;&lt;br /&gt;
 int main (int argc, char ** argv)&lt;br /&gt;
 {&lt;br /&gt;
   int fd_in, fd_out;&lt;br /&gt;
   char * nr_message = “Enter your name, please\n”;&lt;br /&gt;
   char buf[255];&lt;br /&gt;
   fd_in = open(“/dev/tty”, O_RDONLY);&lt;br /&gt;
   fd_out = open(“/dev/tty”, O_WRONLY);&lt;br /&gt;
   write(fd_out, nr_message, strlen(nr_message));&lt;br /&gt;
   read(fd_in, buf, 255);&lt;br /&gt;
   printf(“Your name is %s\n”, buf);&lt;br /&gt;
   return EXIT_SUCCESS;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
В этой программе мы напрямую обращаемся к устройству, которое соответствует управляющему терминалу ввода/вывода. Вы, конечно, помните, что устройства в Unix/Linux представлены файлами. Файл '''/dev/tty''' предоставляет программе доступ к ее управляющему терминалу. Иначе говоря, для каждой программы файл '''/dev/tty''' представляет тот терминал, который является управляющим терминалом данной программы. Мы открываем устройство '''/dev/tty''' дважды – для чтения и записи. Запись в файл '''/dev/tty''' соответствует выводу данных на экран терминала, а чтение – вводу данных с клавиатуры. Полученные дескрипторы, {{oncolor||red|fd_in}} и {{oncolor||red|fd_out}}, мы будем использовать, соответственно, для ввода/вывода, который нельзя перенаправить. Вся магия перенаправления ввода/вывода основана на том, что программы пользуются потоками ввода-вывода, которые предоставляет им оболочка. Если мы в программе свяжем дескрипторы с конкретным устройством, команды оболочки уже не смогут этого изменить. Таким образом, строка “Enter your name, please” всегда будет выводиться на терминал. С терминала же программа будет считывать ответ пользователя. В то же время, строка, распечатанная с помощью {{oncolor||red|printf()}}, может быть перенаправлена на другое устройство, поскольку {{oncolor||red|printf()}} использует поток вывода, предоставленный оболочкой (мы можем, в принципе, подменить поток, используемый {{oncolor||red|printf()}} по умолчанию, но не будем этого делать).&lt;br /&gt;
&lt;br /&gt;
=== Управление терминалом ===&lt;br /&gt;
&lt;br /&gt;
Управление терминалом осуществляется с помощью структуры {{oncolor||red|termios}}, которая содержит значения и флаги, влияющие на различные параметры терминала. Прежде чем изучать структуру {{oncolor||red|termios}} и работающие с нею функции, необходимо сказать несколько слов о режимах работы терминала. Поведение терминала во многом определяется тем, в каком режиме он находится – каноническом или неканоническом. Примером программы, использующей терминал в каноническом режиме, может служить оболочка ''bash''. В каноническом режиме терминал передает программе символы, введенные пользователем, только после того, как пользователь нажмет клавишу {{oncolor||green|Ввод}}. До тех пор, пока пользователь не нажал {{oncolor||green|Ввод}}, он может редактировать вводимую строку, используя клавиши {{oncolor||green|BackSpace}}, {{oncolor||green|Del}}, {{oncolor||green|Tab}} и им подобные. Если терминал находится в неканоническом режиме, пользователю не требуется нажимать {{oncolor||green|Ввод}} для того, чтобы программа получила напечатанные им символы. В неканоническом режиме программа может получать символы сразу после ввода или с задержкой, по одному или по нескольку, в зависимости от настроек режима терминала. Поскольку в неканоническом режиме все введенные символы сразу же передаются программе, возможность редактировать строку у пользователя отсутствует. Независимо от режима, в котором находится терминал, можно установить некоторые базовые параметры, например, скорость передачи данных и функцию контроля ошибок (очень полезно при модемном соединении). Впрочем, некоторые из них, например отключение отображения вводимых пользователем символов ({{oncolor||red|echo}}), могут с пользой применяться и в современных программах.&lt;br /&gt;
&lt;br /&gt;
Структура {{oncolor||red|termios}} позволяет управлять флагами и численными параметрами, которые можно разделить на пять групп: ввод, вывод, управление оборудованием, локальные параметры и специальные управляющие символы. Простейшая структура termios состоит из пяти полей, соответствующих перечисленным группам:&lt;br /&gt;
&lt;br /&gt;
 struct termios {&lt;br /&gt;
 // флаги управления вводом&lt;br /&gt;
 tcflag_t c_iflag;&lt;br /&gt;
 // флаги управления выводом&lt;br /&gt;
 tcflag_t c_oflag;&lt;br /&gt;
 // флаги управления оборудованием&lt;br /&gt;
 tcflag_t c_cflag;&lt;br /&gt;
 // флаги управления локальными параметрами&lt;br /&gt;
 tcflag_t c_lflag;&lt;br /&gt;
 // Специальные управляющие символы&lt;br /&gt;
 cc_t c_cc[NCCS]&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
У структуры {{oncolor||red|termios}} могут быть и другие поля, но нас они не интересуют. Обычно работа со структурой {{oncolor||red|termios}} происходит по следующему сценарию (все необходимые функции и типы данных определены в файле '''termios.h'''): с помощью функции {{oncolor||red|tcgetattr(3)}} мы получаем копию структуры, описывающую текущее состояние терминала, и делаем еще одну копию. Затем мы модифицируем значения полей одной из копий {{oncolor||red|termios}} так, чтобы изменить нужные нам параметры терминала, и передаем драйверу терминала новое значение {{oncolor||red|termios}} с помощью функции {{oncolor||red|tcsetattr(3)}}. После того, как работа с терминалом в нестандартном режиме закончена, мы восстанавливаем исходное состояние терминала с помощью сохраненной копии исходной структуры termios и функции {{oncolor||red|tcsetattr()}}. Первым аргументом функции {{oncolor||red|tcgetattr()}} должен быть дескриптор файла, соответствующего терминалу. Вторым аргументом является указатель на структуру {{oncolor||red|termios}}, в которой функция возвращает текущие настройки терминала. Первым параметром функции {{oncolor||red|tcsetattr()}} также служит дескриптор файла терминала. Второй параметр используется для передачи флагов, определяющих, когда изменения параметров терминала должны вступить в силу. Третьим параметром {{oncolor||red|tcsetattr()}} является указатель на структуру termios, содержащую новые параметры.&lt;br /&gt;
&lt;br /&gt;
Ключевой момент во всем этом – модификация полей структуры {{oncolor||red|termios}}. Первые четыре поля структуры содержат комбинации флагов, определяющих параметры терминала. Пятое поле представляет собой массив значений. Индексам этого массива соответствуют специальные константы, с помощью которых мы можем понять значение элементов массива. Рассмотрим сначала поля {{oncolor||red|termios}}, содержащие флаги. Полное описание флагов (а их довольно много) можно найти на странице man, посвященной {{oncolor||red|termios}}. Я перечислю здесь только некоторые флаги, которые устанавливаются в поле {{oncolor||red|c_lflag}}, поскольку они представляются мне наиболее интересными. Флаг {{oncolor||red|ECHO}} управляет отображением вводимых символов на экране монитора. Если он установлен, символы отображаются, в противном случае – нет. Флаг {{oncolor||red|ECHOE}} делает то же, что флаг {{oncolor||red|ECHO}}, но только для управляющих символов, стирающих другие символы или строки (например, BackSpace). Поскольку неканонический режим не поддерживает редактирование строки, в этом режиме флаг {{oncolor||red|ECHOE}} игнорируется. Если установлен {{oncolor||red|ICANON}}, терминал находится в каноническом режиме, в противном случае – в неканоническом. Флаг {{oncolor||red|IEXTEN}} переводит терминал в режим расширенной обработки вводимых символов. От того, установлен ли флаг {{oncolor||red|ISIG}}, зависит, будут ли специальные комбинации клавиш, такие как {{oncolor||green|Ctrl-C}} и {{oncolor||green|Ctrl-Z}}, инициировать соответствующие им сигналы.&lt;br /&gt;
&lt;br /&gt;
Из констант, соответствующих индексам массива {{oncolor||red|c_cc[]}}, наибольший интерес представляют две – {{oncolor||red|VMIN}} и {{oncolor||red|VTIME}}. Чтобы объяснить важность этих параметров, рассмотрим подробнее работу терминала в неканоническом режиме. В каноническом режиме сигналом завершения ввода данных является нажатие клавиши {{oncolor||green|Ввод}}. Любая функция, считывающая данные с терминала, вернет управление вызвавшей ее программе только после того, как пользователь нажмет эту клавишу. При работе терминала в неканоническом режиме дело обстоит сложнее. В этом режиме нет сигнала, который бы оповещал систему о том, что ввод данных окончен и функция чтения данных должны вернуть управление. Поведение функций, читающих данные в этом режиме, зависит от параметров {{oncolor||red|termios.c_cc[VMIN]}} и {{oncolor||red|termios.c_cc[VTIME]}}. Параметр {{oncolor||red|termios.c_cc[VMIN]}} указывает минимальное число введен- ных символов, после которого функция, считывающая данные, может вернуть управление программе. Параметр {{oncolor||red|termios.c_cc[VTIME]}} указывает максимальное время ожидания ввода (после ввода первого символа), по прошествии которого функция чтения данных возвращает управление, независимо от того, сколько символов было прочитано. Если обоим этим параметрам присвоены значения, больше нуля, функция чтения данных вернет управление после того, как будет выполнено требование одного из параметров. Если функция получит количество символов, заданное в параметре {{oncolor||red|termios.c_cc[VMIN]}} до истечения срока времени, заданного в параметре {{oncolor||red|termios.c_cc[VTIME]}}, она вернет управление и передаст программе соответствующее количество символов. Если заданный промежуток времени истечет до того, как функция считает указанное ей количество символов, функция вернет управление и передаст программе те символы, которые она успела считать. При этом, как следует из сказанного выше, функция чтения данных вернет как минимум один символ. Если одному из параметров {{oncolor||red|termios.c_cc[VMIN]}} или {{oncolor||red|termios.c_cc[VTIME]}} присвоено нулевое значение, а другому – ненулевое, то условием возврата из функции чтения данных становится значение ненулевого параметра. Наконец, если оба параметра имеют нулевые значения, функция чтения данных всегда будет возвращать управление немедленно. Если к моменту вызова функции чтения данных в потоке ввода были символы, буфер функции будет заполнен ими, иначе функция чтения данных вернет пустой буфер.&lt;br /&gt;
&lt;br /&gt;
Вернемся к функции {{oncolor||red|tcsetattr()}}. Во втором параметре этой функции может быть передан один или несколько нижеследующих флагов (для&lt;br /&gt;
комбинации флагов используется оператор {{oncolor||red|&amp;amp;#124;}}).&lt;br /&gt;
* '''TCSANOW''' – изменения параметров терминала вступают в силу немедленно.&lt;br /&gt;
* '''TCSADRAIN''' – изменения параметров терминала вступают в силу после того, как все данные, записанные ранее в файл устройства, будут переданы самому устройству. Это значение обычно используется, если новые значения полей {{oncolor||red|termios}} изменяют параметры вывода данных.&lt;br /&gt;
* '''TCSAFLUSH''' – изменения параметров терминала вступают в силу после того, как все данные, записанные ранее в файл устройства, будут переданы самому устройству. Все данные, которые в этот момент были введены с клавиатуры, но еще не прочитаны программой, при этом теряются.&lt;br /&gt;
* '''TCSASOFT''' – этот флаг заставляет функцию игнорировать значения полей {{oncolor||red|c_cflag}}, {{oncolor||red|c_ispeed}} и {{oncolor||red|c_ospeed}} структуры {{oncolor||red|termios}}. Поля {{oncolor||red|c_ispeed}} и {{oncolor||red|c_ospeed}} управляют скоростью передачи входящих и исходящих данных. Поскольку мы не рассматриваем подключение терминала с помощью модема, эти поля нас не интересуют.&lt;br /&gt;
&lt;br /&gt;
Настало время освежить теорию практикой. Рассмотрим два примера, в которых изменение свойств терминала может оказаться полезным. Первый из них – это консольная программа, предназначенная для ввода пароля. Как вы знаете, во время ввода пароля такие программы не отображают никаких символов. Теперь вы также догадываетесь, как они это делают – им достаточно передать системе структуру {{oncolor||red|termois}} со сброшенным флагом {{oncolor||red|ECHO}}. Программа ''passwdmode'' (файл '''passwdmode.c''') демонстрирует эту технику:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;termios.h&amp;gt;&lt;br /&gt;
 #define BUF_SIZE 15&lt;br /&gt;
 int main (int argc, char ** argv)&lt;br /&gt;
 {&lt;br /&gt;
   struct termios oldsettings, newsettings;&lt;br /&gt;
   char password[BUF_SIZE+1];&lt;br /&gt;
   int len;&lt;br /&gt;
   sigset_t newsigset, oldsigset;&lt;br /&gt;
   sigemptyset(&amp;amp;newsigset);&lt;br /&gt;
   sigaddset(&amp;amp;newsigset, SIGINT);&lt;br /&gt;
   sigaddset(&amp;amp;newsigset, SIGTSTP);&lt;br /&gt;
   sigprocmask(SIG_BLOCK, &amp;amp;newsigset, &amp;amp;oldsigset);&lt;br /&gt;
   tcgetattr(fileno(stdin), &amp;amp;oldsettings);&lt;br /&gt;
   newsettings = oldsettings;&lt;br /&gt;
   newsettings.c_lflag &amp;amp;= ~ECHO;&lt;br /&gt;
   tcsetattr(fileno(stdin), TCSAFLUSH, &amp;amp;newsettings);&lt;br /&gt;
   printf(“Enter password and press [Enter]\n”);&lt;br /&gt;
   len = read(fileno(stdin), password, BUF_SIZE);&lt;br /&gt;
   password[len] = 0;&lt;br /&gt;
   tcsetattr(fileno(stdin), TCSANOW, &amp;amp;oldsettings);&lt;br /&gt;
   sigprocmask(SIG_SETMASK, &amp;amp;oldsigset, NULL);&lt;br /&gt;
   printf(“Your password is %s\n”, password);&lt;br /&gt;
   return EXIT_SUCCESS;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
В начале программы мы блокируем сигналы {{oncolor||red|SIGINT}} и {{oncolor||red|SIGTSTP}} (зачем это нужно, я объясню ниже). Затем с помощью функции {{oncolor||red|tcgetattr()}} мы заполняем переменную {{oncolor||red|oldsettings}} типа {{oncolor||red|struct termios}} текущими значениями параметров терминала. Далее мы копируем содержимое {{oncolor||red|oldsettings}} в переменную {{oncolor||red|newsettings}}. Строка newsettings.c_lflag &amp;amp;= ~ECHO; cбрасывает флаг {{oncolor||red|ECHO}} в структуре {{oncolor||red|newsettings}}. Остальные параметры терминала остаются без изменений. Далее, с помощью функции {{oncolor||red|tcsetattr()}} мы устанавливаем новые параметры. Теперь терминал не будет выводить на экран символы, вводимые пользователем, и мы можем вызвать функцию, считывающую значение пароля. После этого программа восстанавливает прежнее состояние терминала. После этого можно разблокировать заблокированные сигналы. Мы распечатываем строку с введенным «паролем» (не вздумайте вводить в программе какой-нибудь настоящий пароль, иначе злоумышленник, прячущийся за вашей спиной, обязательно его увидит). Зачем мы блокировали сигналы во время ввода пароля? Представьте себе, что в то время, когда программа ожидает ввода пароля, пользователь передумал и захотел завершить ее с помощью {{oncolor||green|Ctrl-C}}. Если программа завершится в этот момент, состояние терминала не будет восстановлено, и символы, вводимые пользователем, по-прежнему не будут отображаться. Это не смертельно, но неудобно. Вот почему программы, ожидающие ввода пароля, временно блокируют некоторые сигналы.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим теперь другой случай. Представьте себе, что программа выполняет некую длительную операцию, и вы хотите, чтобы у пользователя была возможность прервать ее, не прибегая к таким средствам, как сигналы. Для этого программа может периодически проверять, не нажал ли пользователь клавишу выхода, например {{oncolor||green|q}}. Однако если терминал находится в каноническом режиме, пользователю придется нажать еще и «Ввод», чтобы программа могла считать символ, и это не говоря о том, что в каноническом режиме функции чтения данных по умолчанию блокируют выполнение программы до появления данных. Нам нужно, чтобы функция ввода, например, {{oncolor||red|getchar()}}, проверяла наличие в потоке ввода символа {{oncolor||red|q}}, причем без всякого дополнительного символа ввода, но возвращала управление немедленно, независимо от того, есть символ в потоке ввода или нет. Все это очень просто сделать, переведя терминал в неканонический режим, что демонстрирует программа ''pressq'' (файл '''pressq.c''')&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;termios.h&amp;gt;&lt;br /&gt;
 int main (int argc, char ** argv)&lt;br /&gt;
 {&lt;br /&gt;
   struct termios oldsettings, newsettings;&lt;br /&gt;
   tcgetattr(fileno(stdin), &amp;amp;oldsettings);&lt;br /&gt;
   newsettings = oldsettings;&lt;br /&gt;
   newsettings.c_lflag &amp;amp;= ~(ECHO|ICANON|ISIG);&lt;br /&gt;
   newsettings.c_cc[VMIN] = 0;&lt;br /&gt;
   newsettings.c_cc[VTIME] = 0;&lt;br /&gt;
   tcsetattr(fileno(stdin), TCSANOW, &amp;amp;newsettings);&lt;br /&gt;
   while(getchar() != ‘q’) {&lt;br /&gt;
     sleep(1);&lt;br /&gt;
     printf(“press [q] to quit\n”);&lt;br /&gt;
   }&lt;br /&gt;
   tcsetattr(fileno(stdin), TCSANOW, &amp;amp;oldsettings);&lt;br /&gt;
   return EXIT_SUCCESS;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Мы получаем структуру с текущими параметрами терминала, и сохраняем ее, как и в предыдущем случае. Затем мы сбрасываем сразу три флага: {{oncolor||red|ECHO}}, {{oncolor||red|ICANON}} и {{oncolor||red|ISIG}}. Что дает сброс флага {{oncolor||red|ECHO}}, вы уже знаете. Мы не хотим, чтобы введенный пользователем символ команды отображался на экране. Сброс флага {{oncolor||red|ICANON}} переводит монитор в неканонический режим, а сброс флага {{oncolor||red|ISIG}} приводит к тому, что ввод специальных символов {{oncolor||green|Ctrl-C}} и {{oncolor||green|Ctrl-Z}} не порождает сигналов. Это еще один способ защитить программу от некорректного завершения в тот момент, когда параметры терминала изменены. Затем мы устанавливаем значения параметров {{oncolor||red|newsettings.c_cc[VMIN]}} и {{oncolor||red|newsettings}}. {{oncolor||red|c_cc[VTIME]}}. Обоим параметрам присваивается значение 0. В результате функция {{oncolor||red|getchar()}} всегда будет возвращать управление немедленно. Далее программа переходит в бесконечный цикл, из которого ее может вывести только появление символа q в потоке ввода. По выходе из цикла мы восстанавливаем параметры терминала и завершаем программу. Необходимо подчеркнуть разницу между блокированием сигналов в программе ''psswdmode'' и сбросом флага {{oncolor||red|ISIG}} в программе ''pressq''. В первом случае обработка сигналов откладывается. Если во время ввода пароля пользователь нажмет {{oncolor||green|Ctrl-C}}, программа получит соответствующий сигнал после того, как пользователь нажмет ввод (и после того, как программа вернет терминал в нормальный режим). Если же вы сбрасываете флаг {{oncolor||red|ISIG}}, специальные сочетания клавиш не будут инициировать сигналы и программа вообще их не получит.&lt;br /&gt;
&lt;br /&gt;
Тема консольного ввода/вывода неисчерпаема, но мы не собираемся на ней долго задерживаться. В следующей статье, последней в этой серии, мы рассмотрим интерфейс {{oncolor||red|terminfo}} и библиотеку ''ncurses''. [http://www.linuxformat.ru LXF]&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-8.png</id>
		<title>Файл:LXF90-Glade-8.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-8.png"/>
				<updated>2008-03-16T15:33:19Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Работающая программа ImageView.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Работающая программа ImageView.&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-7.png</id>
		<title>Файл:LXF90-Glade-7.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-7.png"/>
				<updated>2008-03-16T15:31:58Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Окно с информацией о программе.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Окно с информацией о программе.&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-6.png</id>
		<title>Файл:LXF90-Glade-6.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-6.png"/>
				<updated>2008-03-16T15:31:38Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Форма приложения с кнопками и объектом GtkImage.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Форма приложения с кнопками и объектом GtkImage.&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-5.png</id>
		<title>Файл:LXF90-Glade-5.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-5.png"/>
				<updated>2008-03-16T15:30:11Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Главное окно Glade.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Главное окно Glade.&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-4.png</id>
		<title>Файл:LXF90-Glade-4.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-4.png"/>
				<updated>2008-03-16T15:29:52Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Окно редактора свойств&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Окно редактора свойств&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-3.png</id>
		<title>Файл:LXF90-Glade-3.png</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/%D0%A4%D0%B0%D0%B9%D0%BB:LXF90-Glade-3.png"/>
				<updated>2008-03-16T15:29:22Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Рис. 3: Главное окно палитры.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Рис. 3: Главное окно палитры.&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/LXF90:GTK%2B</id>
		<title>LXF90:GTK+</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/LXF90:GTK%2B"/>
				<updated>2008-03-16T15:18:45Z</updated>
		
		<summary type="html">&lt;p&gt;Human: Новая: == Glade 2.x – визуальная классика == ''{{oncolor||green|ЧАСТЬ 4}} Красивый интерфейс можно запрограммировать, вдалб...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Glade 2.x – визуальная классика ==&lt;br /&gt;
''{{oncolor||green|ЧАСТЬ 4}} Красивый интерфейс можно запрограммировать, вдалбливая бесконечные строчки кода, а можно – легким движением руки, в которой зажата мышь. '''Андрей Боровский''' рассматривает второй способ.''&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
Каждый уважающий себя набор визуальных элементов располагает средством для того, чтобы бросить пару-тройку компонентов на заготовку окна приложения, настроить их свойства и получить остов будущей программы. У ''Qt'' есть ''Qt Designer'', у ''wxWidgets'' есть ''DialogBlocks'', а у ''GTK+'' есть ''Glade''. Если ваш опыт программирования ограничивается такими средами, как Borland C++ Builder или Microsoft Visual C#, приступая к программированию с помощью ''Glade'', вы должны понять одну важную вещь: ''Glade'' – это не IDE. В нем нет ни интегрированного компилятора, ни интерактивного отладчика, ни редактора кода с автоматическим завершением строки. ''Glade 2.x'' генерирует минимальный код, который вам придется дописывать в вашем любимом редакторе, а ''Glade 3.x'' вообще стремится возложить генерацию кода на другие инструменты. Несмотря на то, что в ближайшее время старый ''Glade'' будет вытеснен третьей версией, знакомство с этим инструментом разработки позволит нам взглянуть на структуру сложных программ ''GTK+'' глазами самих авторов набора компонентов. Поэтому данная статья посвящена ''Glade 2.x'', а в следующей статье мы узнаем, чем ''Glade 3.x'' отличается от своего предшественника. Мы воспользуемся ''Glade'' для создания простой программы ImageViewer. Ее исходные тексты можно найти на диске, но я советую вам пройти вместе со мной все шаги по созданию данного приложения.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Glade-1.png|thumb|Рис. 1: Окно выбора типа проекта]]Каждый раз, когда мы создаем новый проект ''Glade'', перед нами появляется диалоговое окно, в котором нам предлагается выбрать тип проекта – ''GTK+'' или ''GNOME'' '''(Рис. 1)'''. Нам нужен ''GTK+''.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Glade-2.png|thumb|Рис. 2: Главное окно Glade]]В среде ''Glade'' в процессе работы может быть открыто несколько окон, постоянными из которых являются три: главное окно, окно палитры и окно редактора свойств объектов. Главное окно '''(Рис. 2)''' содержит меню и панель инструментов для управления проектом. В рабочей части окна расположен список визуальных элементов верхнего уровня.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Glade-3.png|thumb|Рис. 3: Главное окно палитры.]]Окно «Палитра», которое, в том или ином виде, присутствует в каждой среде визуальной разработки, предоставляет нам доступ к пиктограммам визуальных элементов. Окно {{oncolor||green|Палитра}} ''Glade 2.*'' '''(Рис. 3)''' содержит несколько вкладок. Список вкладок зависит от типа проекта (GTK+ или GNOME). При работе с нашим проектом палитра будет содержать три вкладки: {{oncolor||green|GTK+ Основные}}, {{oncolor||green|GTK+ Дополнительные}} и {{oncolor||green|Устаревшие}}.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Glade-4.png|thumb|Рис. 4: Окно редактора свойств]]Окно редактора свойств '''(Рис. 4)''' предназначено, естественно, для редактирования свойств визуальных элементов. Это окно также содержит несколько вкладок. Вкладка {{oncolor||green|Эл. управления}} позволяет настраивать специфические свойства визуального элемента. Вкладка {{oncolor||green|Упаковка}} позволяет настраивать параметры упаковки тех визуальных элементов, которые вложены в какой-либо контейнер. С помощью вкладки {{oncolor||green|Общие}} можно настраивать общие свойства визуальных элементов, а вкладка {{oncolor||green|Сигналы}} предназначена для связывания сигналов и их обработчиков. Наконец, безымянная вкладка, пиктограмма которой изображает инвалидное кресло, позволяет настраивать параметры доступности (accessibility) визуальных элементов GNOME. Эту вкладку мы пока рас-сматривать не будем.&lt;br /&gt;
&lt;br /&gt;
Щелкните по элементу {{oncolor||green|Окно}} на вкладке {{oncolor||green|GTK+}} Основные палитры компонентов. В результате в проект будет добавлен элемент верхнего уровня {{oncolor||green|Окно}} (вы можете видеть его в списке элементов верхнего уровня в главном окне проекта), а перед нами откроется пустое окно со стандартным заголовком. Это окно станет главным окном создаваемого нами приложения. Программа ''GTK+'' может содержать несколько элементов верхнего уровня, и для каждого из них можно открыть независимое окно.&lt;br /&gt;
&lt;br /&gt;
Давайте настроим параметры главного окна программы. Для того, чтобы открыть объект интерфейса верхнего уровня в редакторе свойств, нужно выделить этот объект в главном окне ''Glade''. Перейдя в редакторе свойств на вкладку {{oncolor||green|Эл. управления}}, мы можем указать текст заголовка окна (свойство {{oncolor||green|Заголовок}}). Установите также флажки {{oncolor||green|Ширина по умолчанию}} и {{oncolor||green|Высота по умолчанию}}. В соответствующих наборных счетчиках укажите значения '''{{oncolor||red|200}}''' и '''{{oncolor||red|150}}'''. Таким образом вы зададите начальные размеры окна.&lt;br /&gt;
&lt;br /&gt;
Вы, конечно, помните, что любое приложение ''GTK+'' с более-менее сложным интерфейсом должно использовать контейнеры для управления визуальными элементами. Разработка интерфейса в ''Glade'' также начинается с создания контейнера. Выберите на вкладке палитры {{oncolor||green|GTK+ Основные}} элемент {{oncolor||green|Вертикальный бокс}}. Этому элементу соответствует вертикальный контейнер {{oncolor||red|GtkVBox}}. Перенесите вертикальный контейнер мышью в окно приложения. Во многих редакторах форм этот процесс называется перетаскиванием, поскольку компонент перетаскивается мышью с палитры компонентов в окно формы, но в ''Glade'' все происходит по-другому. Для того чтобы перенести компонент в форму, нужно сначала щелкнуть мышью по этому компоненту в палитре, а затем – по той области на форме, в которой этот компонент должен быть размещен (вот почему мы используем термин «перенос» а не «перетаскивание»). При переносе в форму вертикального контейнера открывается диалоговое окно, в котором ''Glade'' просит нас указать число строк в нем. Cоздайте контейнер с двумя строками. В результате главное окно будет разделено на две горизонтальные области, расположенные одна под другой (для вертикального расположения дочерних элементов). В верхнюю область перенесите с палитры объект {{oncolor||green|Панель инструментов}}. Панель инструментов также представляет собой контейнер, так что при переносе панели в окно приложения мы снова должны указать количество дочерних элементов (на этот раз – кнопок панели). Панель инструментов нашего приложения должна содержать две кнопки. Вы можете заметить, что после переноса панели инструментов в окно формы, размеры верхней области вертикального контейнера подстраиваются под размеры панели, а на самой панели появляются две незаполненные области для размещения кнопок '''(Рис. 5)'''. В эти области мы должны перенести два элемента {{oncolor||green|Toolbar Button}} – кнопки панели инструментов, которым соответствует объект {{oncolor||red|GtkToolButton}}. В окне панели инструментов появляются заготовки кнопок.[[Изображение:LXF90-Glade-5.png|thumb|Рис. 5: Главное окно Glade.]]&lt;br /&gt;
&lt;br /&gt;
=== Что в имени тебе моем ===&lt;br /&gt;
&lt;br /&gt;
Поскольку на этом этапе мы уже работаем с несколькими объектами, нам следует познакомиться с понятием имени объекта. Каждому объекту ''GTK+'' может быть присвоено имя. Это имя хранится в одном из полей объекта, и его не следует путать с именем переменной, которая содержит указатель на объект (имя объекта, хранящееся в самом объекте, по праву можно назвать «именем собственным»). До тех пор, пока наши программы состояли из одного файла и все переменные, содержащие объекты, находились в одной области видимости, имена объектов не имели для нас значения. Однако в сложных проектах, состоящих из нескольких файлов, имена объектов ''GTK+'' играют важную роль, поскольку именно они служат для идентификации объектов. В редакторе свойств объектов на вкладке {{oncolor||green|Эл. управления}} присутствует свойство {{oncolor||green|Имя}}, которое позволяет вам получить доступ к имени объекта на этапе визуального программирования. Две кнопки, которые вы добавили на панель инструментов, имеют имена {{oncolor||red|toolbutton1}} и {{oncolor||red|toolbutton2}}. Я предполагаю, что вы добавляли кнопки в порядке слева направо, то есть первой слева является кнопка {{oncolor||red|toolbutton1}}.&lt;br /&gt;
&lt;br /&gt;
Только что созданные кнопки выглядят совсем не так, как нам хотелось бы. Для того, чтобы придать кнопкам требуемый вид, мы должны отредактировать их свойства. Выберите в окне формы кнопку {{oncolor||red|toolbutton1}} и перейдите в редактор свойств, на вкладку {{oncolor||green|Эл. управления}}. Свойству {{oncolor||green|Метка}} присвойте значение {{oncolor||green|Открыть}}. Затем щелкните по значку раскрывающегося списка в поле свойства {{oncolor||green|Иконка}}, в открывшемся списке выберите пиктограмму {{oncolor||green|Открыть}}. Нам необходимо создать заготовку обработчика для сигнала кнопки {{oncolor||red|clicked}}. Перейдите на вкладку {{oncolor||green|Сигналы}} редактора свойств и щелкните кнопку с многоточием справа от строки ввода {{oncolor||green|Сигнал}}. Перед вами раскрывается список сигналов, в котором следует выбрать сигнал {{oncolor||red|clicked}}. В строке {{oncolor||green|Обработчик}} появляется имя обработчика сигнала (по умолчанию – {{oncolor||red|on_toolbutton1_clicked}}). Щелкните кнопку {{oncolor||green|Добавить}}. В результате новая функция будет добавлена в список обработчиков сигналов кнопки {{oncolor||red|toolbutton1}}.&lt;br /&gt;
&lt;br /&gt;
Перейдем теперь к редактированию свойств кнопки {{oncolor||red|toolbutton2}}. Свойству {{oncolor||green|Метка}} второй кнопки присвоим значение {{oncolor||green|О программе}}. В списке значений свойства {{oncolor||green|Иконка}} выберем значение {{oncolor||green|Справка}}, затем создадим заготовку обработчика сигнала {{oncolor||red|clicked}} (назовем его {{oncolor||red|on_toolbutton2_clicked}}), так же как и в предыдущем случае.&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Glade-6.png|thumb|Рис. 6: Форма приложения с кнопками и объектом GtkImage.]]В нижнюю область вертикального контейнера следует перенести элемент палитры {{oncolor||green|Изображение}} (объект {{oncolor||red|GtkImage}}, имя объекта по умолчанию – {{oncolor||red|image1}}). Выделите объект {{oncolor||red|image1}} в окне формы. Перейдите на вкладку {{oncolor||green|Упаковка}} редактора свойств и присвойте значение {{oncolor||green|Да}} свойству {{oncolor||green|Заполнение}}. Далее, выделите в окне формы палитру инструментов (объект {{oncolor||red|toolbar1}} типа {{oncolor||red|GtkToolbar}}). Перейдите на вкладку {{oncolor||green|Упаковка}} редактора свойств и также присввойте значение {{oncolor||green|Да}} свойству {{oncolor||green|Заполнение}} '''(Рис. 6)'''.&lt;br /&gt;
&lt;br /&gt;
=== Заголовок ===&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Glade-7.png|thumb|Рис. 7: Окно с информацией о программе.]]Мы должны еще добавить в проект окно с информацией о программе. Это просто, поскольку необходимое окно входит в набор визуальных компонентов ''GTK+'' '''(Рис. 7)'''. Вы найдете его на вкладке {{oncolor||green|GTK+ Дополнительные}} палитры компонентов (элемент {{oncolor||red|About Dialog}}, объект {{oncolor||red|GtkAboutDialog}}). Окно с информацией о программе является элементом верхнего уровня, поэтому после щелчка мышью в палитре компонентов объект {{oncolor||red|aboutdialog1}} появится в списке элементов верхнего уровня. Перейдя на вкладку {{oncolor||green|Эл. управления}} редактора свойств, вы сможете настроить основные свойства этого диалогового окна (название программы, имя автора, информацию о правах и т.д.). Никаких обработчиков сигналов для этого окна создавать не нужно, поскольку все необходимые обработчики создаются по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Сохраним наш проект. Как уже отмечалось, ''Glade 2.*'' позволяет генерировать исходный код приложения. Для этого нужно щелкнуть на кнопку {{oncolor||green|Построить}}. Теперь мы можем скомпилировать нашу программу (точнее, ту ее часть, которую мы создали). Перейдем в директорию проекта и выполним файл '''autogen.sh'''. В результате будут созданы сценарий {{oncolor||red|configure}} и make-файл. Мы можем собрать программу с помощью команды '''make'''. Двоичный файл программы будет создан в директории '''src'''. Если вы запустите программу на этом этапе (я рекомендую первый раз запустить программу с консоли), то заметите две неприятные вещи. Во-первых, окно с информацией о программе само собой появляется вместе с главным окном программы. Во вторых, после закрытия главного окна программы ее работа не завершается (это заметно, если запустить программу из окна консоли). Для того, чтобы исправить ситуацию с окном {{oncolor||red|aboutdialog1}}, нам нужно отредактировать файл '''src/main.c'''. Откройте этот файл в текстовом редакторе и удалите из него строки&lt;br /&gt;
&lt;br /&gt;
 aboutdialog1 = create_aboutdialog1 ();&lt;br /&gt;
 gtk_widget_show (aboutdialog1);&lt;br /&gt;
&lt;br /&gt;
Как вы, конечно, поняли, файл '''main.c''' содержит главную функцию программы. По умолчанию этот файл содержит код для создания и отображения на экране всех визуальных элементов верхнего уровня. Помимо файла '''main.c''' среда ''Glade'' создала еще несколько файлов исходных текстов в директории '''src'''. Файлы '''interface.c''' и '''interface.h''' содержат код, отвечающий за работу элементов управления, которые мы создали в режиме визуального программирования. Файл '''support.c/support.h''' включают некоторые вспомогательные функции. Обработчики сигналов, которые мы создали в редакторе свойств ''Glade'', объявлены в файле '''callbacks.h''', а определены – в файле '''callbacks.c''' (вы можете изменить имена файлов исходных текстов, заданные по умолчанию, в окне настроек ''Glade''). Только файлы '''main.c''' и '''callbacks.c''' предназначены для ручного редактирования. Текст остальных файлов перезаписывается ''Glade'' в процессе генерации кода. Теперь вспомним первые уроки программирования ''GTK+''. Для того, чтобы программа завершалась вместе с закрытием главного окна, необходимо определить обработчик сигнала destroy объекта окна. В главном окне ''Glade'' выделите главное окно приложения и перейдите на вкладку «Сигналы» редактора свойств. Выберите в списке сигналов сигнал destroy (его не следует путать с доступным там же событием “destroy event”) и создайте заготовку обработчика для этого сигнала точно так же, как вы создавали заготовки обработчиков сигналов {{oncolor||red|clicked}}. Сгенерируйте заново исходный код, нажав кнопку «Построить». Откройте в текстовом редакторе файл '''callbacks.c'''. Найдите заготовку обработчика {{oncolor||red|on_window1_destroy()}} и добавьте в него вызов функции {{oncolor||red|gtk_main_quit()}}:&lt;br /&gt;
&lt;br /&gt;
 void on_window1_destroy (GtkObject * object, gpointer user_data)&lt;br /&gt;
 {&lt;br /&gt;
   gtk_main_quit();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Мы используем тот же метод завершения программы, что и во всех предыдущих примерах. Сохраните файл '''callbacks.c'''. Теперь можете перекомпилировать и запустить программу снова. Окно описания программы уже не появляется, а закрытие главного окна программы приводит к ее завершению. После внесения изменений в свойства визуальных объектов вы должны каждый раз заново генерировать исходный код (и, конечно, сохранять все изменения, сделанные в исходных текстах вручную). Что произойдет, если вы сначала отредактируете код одного обработчика сигнала, а затем добавите новый обработчик в режиме визуального редактирования? Ничего страшного не случится. ''Glade'' добавит новый код в файл '''callbacks.c''', и не тронет изменения, сделанные вами (этим свойством обладают только файлы '''callbacks.c''' и '''main.c''').&lt;br /&gt;
&lt;br /&gt;
Завершающая часть работы над нашей программой связана с добавлением кода в обработчики событий {{oncolor||red|clicked}} двух кнопок. Сами функции-обработчики {{oncolor||red|on_toolbutton1_clicked()}} и {{oncolor||red|on_toolbutton2_clicked()}} уже определены в файле '''callback.c'''. Первая функция должна вызывать диалоговое окно выбора файла и загружать выбранный пользователем файл изображения в компонент {{oncolor||red|image1}}:&lt;br /&gt;
&lt;br /&gt;
 void&lt;br /&gt;
 on_toolbutton1_clicked (GtkToolButton * toolbutton, gpointer user_data)&lt;br /&gt;
 {&lt;br /&gt;
   GtkWidget * file_chooser_dialog;&lt;br /&gt;
   file_chooser_dialog = gtk_file_chooser_dialog_new(“Открыть”, NULL,&lt;br /&gt;
     GTK_FILE_CHOOSER_ACTION_OPEN,&lt;br /&gt;
     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,&lt;br /&gt;
     GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);&lt;br /&gt;
      if (gtk_dialog_run(GTK_DIALOG (file_chooser_dialog)) == GTK_RESPONSE_ACCEPT)&lt;br /&gt;
      {&lt;br /&gt;
          GtkWidget * toplevel;&lt;br /&gt;
          GtkWidget * image;&lt;br /&gt;
          char *filename;&lt;br /&gt;
          filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser_dialog));&lt;br /&gt;
          toplevel = gtk_widget_get_toplevel(GTK_WIDGET(toolbutton));&lt;br /&gt;
          image = lookup_widget(GTK_WIDGET(toplevel), “image1”);&lt;br /&gt;
          gtk_image_set_from_file(GTK_IMAGE(image), filename);&lt;br /&gt;
          gtk_window_set_title(GTK_WINDOW(toplevel), filename);&lt;br /&gt;
          g_free (filename);&lt;br /&gt;
      }&lt;br /&gt;
      gtk_widget_destroy (file_chooser_dialog);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Все необходимые заголовочные файлы включены в файл '''callbacks.c''', так что мы можем о них не беспокоиться. Диалоговое окно выбора файла реализуется объектом {{oncolor||red|GtkFileChooserDialog}}. Объект создается функцией {{oncolor||red|gtk_file_chooser_dialog_new()}}. В первом параметре этой функции передается заголовок создаваемого окна. Второй параметр может содержать ссылку на родительский визуальный элемент. Третий параметр служит для передачи константы, которая указывает, для чего предназначено диалоговое окно – для открытия или для сохранения файла. Далее следует список параметров, состоящий из имен кнопок и констант, которые должны идентифицировать эти кнопки. Список может содержать описание одной или нескольких кнопок и должен заканчиваться значением '''{{oncolor||red|NULL}}'''. Функция {{oncolor||red|gtk_dialog_run()}} делает диалоговое окно видимым и возвращает управление после того, как пользователь нажмет одну из кнопок. При этом функция возвращает значение, сопоставленное нажатой кнопке при вызове функции {{oncolor||red|gtk_file_chooser_dialog_new()}}. Если пользователь нажал кнопку «Открыть», имя которой задано в константе {{oncolor||red|GTK_STOCK_OPEN}}, функция {{oncolor||red|gtk_dialog_run()}} возвращает значение {{oncolor||red|GTK_RESPONSE_ACCEPT}}. В случае выбора пользователем кнопки «Открыть» мы должны узнать имя выбранного файла, получить указатель на объект {{oncolor||red|image1}} и загрузить файл в этот объект. Если вас удивляет, что я включил получение указателя на объект {{oncolor||red|image1}} в список наших задач, то вспомните, что у вас нет доступа к переменной, которая хранит этот указатель. Для того, чтобы получить указатель на объект {{oncolor||red|image1}}, мы должны воспользоваться функцией поиска объектов в иерархии визуальных компонентов нашего приложения. Мы начинаем поиск объектов с того, что находим визуальный элемент верхнего уровня. Указатель на визуальный элемент верхнего уровня мы получаем с помощью функции {{oncolor||red|gtk_widget_get_toplevel()}}. В поисках нужного объекта функция {{oncolor||red|gtk_widget_get_toplevel()}} перебирает иерархию визуальных элементов, начиная с того элемента, чей указатель передан ей в единственном параметре. В качестве стартового значения для поиска мы передаем функции {{oncolor||red|gtk_widget_get_toplevel()}} указатель на объект-кнопку, для которой вызван обработчик {{oncolor||red|on_toolbutton1_clicked()}} (адрес этого объекта передается функции обработчику в параметре toolbutton, и это единственный адрес объекта нашего приложения, которым мы располагаем в данный момент). Адрес объекта, представляющего элемент верхнего уровня (в нашем случае это объект {{oncolor||red|window1}} – главное окно приложения) мы сохраняем в переменной {{oncolor||red|toplevel}}. Далее мы получаем указатель на объект image1 с помощью функции {{oncolor||red|lookup_widget()}} (эта функция сгенерирована ''Glade'' для нашего проекта и объявлена в файле '''support.h'''). Функция {{oncolor||red|lookup_widget()}} позволяет найти визуальный объект по его имени. Документация гласит, что первым аргументом {{oncolor||red|lookup_widget()}} должен быть указатель на визуальный элемент верхнего уровня, либо указатель на любой другой элемент иерархии приложения. В качестве отправной точки поиска мы выбираем элемент верхнего уровня, во-первых, потому, что так красивее, и во-вторых, потому, что у нас все равно уже есть указатель на объект главного окна. Вторым аргументом {{oncolor||red|lookup_widget()}} должно быть имя искомого визуального элемента. Указатель на объект {{oncolor||red|image1}} сохраняется нами в переменной image. Мы получаем имя выбранного пользователем файла с помощью функции {{oncolor||red|gtk_file_chooser_get_filename()}} и загружаем хранящееся в файле изображение в объект {{oncolor||red|image1}} с помощью функции {{oncolor||red|gtk_image_set_from_file()}}. Остальной код обработчика должен быть вам понятен. Осталось заполнить обработчик сигнала clicked кнопки toolbutton2:&lt;br /&gt;
&lt;br /&gt;
 void&lt;br /&gt;
 on_toolbutton2_clicked(GtkToolButton *toolbutton, gpointer user_data)&lt;br /&gt;
 {&lt;br /&gt;
   GtkWidget * about_dialog;&lt;br /&gt;
   about_dialog = create_aboutdialog1();&lt;br /&gt;
   gtk_widget_show(about_dialog);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[[Изображение:LXF90-Glade-8.png|thumb|Рис. 8: Работающая программа ImageView.]]Получить указатель на объект {{oncolor||red|aboutdialog1}} очень просто. В файле '''interface.h''' определена функция {{oncolor||red|create_aboutdialog1()}}, которая создает объект окна описания программы и возвращает указатель на него. Нам остается только вывести окно на экран с помощью {{oncolor||red|gtk_widget_show()}}. Это те самые два вызова функций, которые нам пришлось удалить из файла '''main.c''', для того, чтобы окно описания программы не появлялось тогда, когда не надо. Теперь мы можем проверить, как работает наша программа '''(Рис. 8)'''. [http://www.linuxformat.ru LXF]&lt;/div&gt;</summary>
		<author><name>Human</name></author>	</entry>

	</feed>