From: geekkoo <http://linuxportal.ru/>
Subject: Печать через Samba
Печатаем через Samba.
Начну издалека. Классическая система печати Линукс lpr (или ее более
современная модификация lprng) - это, на мой взгляд, такой
образцово-показательный пример Unix-way: когда решение какой-то задачи
достигается с помощью нескольких отдельных приложений, слепленных
между собой толстым слоем shell-glue. Такой подход имеет как свои
достоинства (экономичность - одно и то-же приложение может
использоваться в нескольких различных задачах), так и недостатки
(сложность установки и администрирования). Если для вас недостатки
перевешивают достоинства, и вы предпочитаете иметь дело с одной "все в
одном" программой, то советую обратить внимание на систему печати
cups, которая в данном тексте рассматриваться не будет.
Диспозиция
Имеются два компьютера в домене Самба с операционными системами MS
Windows (98, доменное имя Alex) и Линукс (Slackware-8.1, доменное имя
Ustas). К компьютеру с Windows подключен принтер (HP LaserJet IIP),
расшаренный по сети как HP. Задача - настроить печать из Линукса на
этом принтере. Для этого вам как минимум необходимо установить пакеты
lprng (система печати, spooler), ghostscript (интерпретатор
postscript, необходим, т.к. принтер H LaserJet IIP не является
постскриптовским), apsfilter (фильтр печати, bash-скрипт, котрорый
переформатирует задания, посланные на печать), psutils (набор утилиток
для манипулирования постскрипт файлами, в Slackware8.1 он включен в
пакет a2ps) и samba. Замечу, что для lprng "официальным" фильтром
является ifhp, но мне он показался более сложным в настройке, и
поэтому я предпочитаю использовать именно apsfilter.
Postscript, PCL, PJL ...
Первое, с чем нужно разобраться - это понять какой принтер у вас стоит
- постскриптовский или нет. Дело в том, что большинство линуксовых
приложений при печати создают постскрипт файл, который они просто
передают spooler'у, и тот в зависимости от своих настроек либо
напрямую отправляет его на принтер (можно сказать, что постскрипт файл
- это print-job файл для постскрипт принтеров), либо пытается его
каким-то образом преобразовать. Постскрипт - это достаточно
высокоуровневый язык, и поэтому, для того чтобы уметь интерпретировать
его, постскрипт принтеру требуется более сложная электронная начинка
(что, соответственно, увеличивает и его стоимость), чем более
примитивным PCL (Printer Control Language, к этому типу относится как
раз HP LJ IIP) или PJL (Print Job Language) принтерам. По причине
более высокой цены постскрипт принтеры в российских условиях не очень
прижились, и скорее всего вам придется иметь дело с PCL/PJL принтером
(я, например, с постскрипт-принтерами ни разу не сталкивался, и
поэтому в данном тексте их рассматривать не буду). Но в таком случае,
ваш spooler (точнее фильтр печати) должен уметь "софтверно"
интерпретировать постскрипт-файл и преобразовывать его в формат
понятный PCL/PJL принтеру, т.е. взять на себя часть работы, которую
постскрипт принтер выполняет, так сказать, "хардверно". В некотором
смысле ситуация здесь аналогична ситуации с OpenGL приложениями и
видеокартами (хотя механизм там и здесь совершенно различен). Если
видео карта не имеет хардверного ускорения, то приложение (точнее
Xserver, если речь идет о Линуксовом окружении) должно прибегать к
услугам software rendering библиотеки (MesaGL), преобразующей вызовы
OpenGL функций в последовательности графических команд (X protocol'а).
Немного "теории".
Как вообще устроена система печати в Линуксе? Во-первых это демон
печати lpd, который должен быть запущен, прежде, чем вы попытаетесь
что-либо напечатать. Задания на печать помещаются с помощью команды
lpr -P{имя принтера} -Z{опции принтера} {файл}. База данных имеющихся
в системе принтеров и основной конфигурационный файл - это
/etc/printcap. Вот как он выглядит у меня:
# APS1_BEGIN:printer1
# - don't delete start label for apsfilter printer1
# - no other printer defines between BEGIN and END LABEL
AlexHP|ljet2p;r=600x600;q=medium;c=full;p=a4;m=auto:
:lp=|/var/spool/lpd/AlexHP/Ustas_to_Alex:
:if=/etc/apsfilter/basedir/bin/apsfilter:
:sd=/var/spool/lpd/AlexHP:
:lf=/var/spool/lpd/AlexHP/log:
:af=/var/spool/lpd/AlexHP/acct:
:mx#0:
:sh:
# APS1_END - don't delete this
Каждому принтеру соответствует абзац, начинающийся со строк вида
AlexHP|ljet2; ({имя принтера}|{имя драйвера}). Если lpr запущена без
опции -P, то задание будет отправлено на дефолтный принтер - тот что
задается переменной окружения $PRINTER, или (если такая переменная не
определена) стоящий первым в файле printcap. Каждый из системных
принтеров хранит свои временный файлы, некоторые настройки и логи в
директории sd=AlexHP (spool directory). Именно сюда команда lpr
складывает файлы, посланные на печать. Демон печати периодически
проверяет содержимое этих директорий и при обнаружении новых заданий
отправляет их либо сразу в файл lp, либо предварительно передавать их
для обработки фильтру if (input filter), если такая строка есть в
файле printcap. Файл lp может быть как файлом устройства (типа
/dev/lp0), так и стандартным вводом конвеера команд (как это сделано у
меня). В принципе, на печать могут быть отправлены файлы любого
формата, при условии, что фильтр сумеет их распознать и
переформатировать. Поэтому, первое что делает apsfilter при получении
заданий - пытается по начальным байтам, при помощи утилитки file
распознать его формат (например на принтер может быть послан исходник
C-программы - apsfilter вызовет программку a2ps и преобразует его в
постскрипт ). Но главное, что должен сделать фильтр - это
преобразовать исходный файл в формат пригодный для печати на вашем
принтере. Для этого apsfilter использует вызов ghostscript, являющийся
универсальным интерпретатором языка постскрипт. В какой именно формат
будет преобразован исходный файл определяется опцией ghostscript
-sDEVICE. Этот параметр может быть как названием модели принтера
(например в моем /еtc/printcap первое слово после имени принтера -
ljet2p - это и есть драйвер ghostscripta), так и любым другим
устройством на которое предполагается выводить постскрипт файл
(например -sDEVICE=x11 позволяет отображать постскрипт файл на
дисплее, -sDEVICE=jpeg - конвертирует постскрипт файл в jpeg). Если у
вас возник вопрос "Где взять драйвер для моего принтера?", то первое
что вы должны сделать - это проверить нет ли подходящего драйвера в
поставке ghostscript (а он идет вместе с довольно обширным набором
драйверов).
Все что следует за именем принтера и его драйвером в первой строке
файла /etc/printcap - это дефолтные значения пользовательских опций,
определяющие разрешение (r=600x600), качество печати (q=medium),
формат бумаги (p=a4) и т.д. (полный список - man apsfilter). Значения
по умолчанию могут быть перопределены с помощью -Z опций в командной
строке при отправке файла на печать. Z-опции передаются
непосредственно фильтру и поэтому их формат зависит от выбранного вами
фильтра (для apsfilter они состоят из значений опций, разделенных
двоеточиями).
Настраиваем сетевое соединение.
Перейдем теперь к практике. Первое в чем вам стоит убедиться - что
принтер виден по сети и что у вас есть к нему доступ (если у вас Samba
настроена и работает, то, в принципе, этот шаг можно пропустить, но
лишняя проверка никогда не помешает). Для этого в командной строке
набираете
smbclient -L //Alex
У меня в сети уровень security - share (т.e. любой юзер знающий
пароль, запирающий какой-нибудь ресурс или компьютер, имеет доступ к
этому ресурсу), поэтому я не указываю user-name (опция -U {имя
пользователя}). После формальностей, связанных с заполнением пароля, -
я вижу список ресурсов, доступных на этом компьютере, и среди них
принтер HP. Теперь можно попробовать "напечатать" на нем что-нибудь. Я
предпочитаю для этой цели пользоваться командой smbspool, которая
входит в пакет samba, но можно воспользоваться тем же самым
smbclient+print или скриптом smbprint. Я создаю one-liner такого вида:
#!/usr/bin/sh
#Samba-Print on //Alex/HP
/usr/bin/smbspool smb://:igels@Alex/HP 1 1 1 1 --
и сохраняю его как ~/Ustas_to_Alex (этот файл дожен быть исполняемым -
такчто chmod u+x ~/Ustas_to_Alex). Команда :
echo -ne f | ~/Ustas_to_Alex
должна заставить принтер отмотать одну страницу.
Небольшая справка по smbspool (для тех кто не любит читать manы).
Первый аргумент - {протокол}://{юзер}:{пароль}@{имя хоста}/{сетевое
имя принтера}. Поскольку у меня security=share, то имя юзера я
опускаю, но сам принтер запаролен, поэтому пароль (igels) я оставил.
Следующие аргументы - (job-id user title copies options) хотя и
являются обязательными, но на самом деле smbspool их не использует,
так что можно взять любые значения.
Последним идет имя файла (отсутствующее), что (как обычно)
предполагаетиспользование в качестве такового стандартный ввод.
Выбираем драйвер.
Вот это самое тонкое место во всей процедуре настройки печати. Первое,
куда нужно заглянуть в поисках драйверов - это gs --help. Помимо
всевозможных опций ghostscripta эта команда выдаст список драйверов
поддерживаемых ghostsscript-oм (их количество зависит от того как был
собран ghostscript - включены в него contributed и uni-print драйвера
или нет). Иногда по имени драйвера можно догадаться какой именно
модели принтера он соответствует. В сложных случаях можно заглануть
еще в два файла, содержащихся в исходниках ghostscripta - devs.mak и
contrib.mak. В комментариях в начале этих файлов приведены списки
драйверов и соответствующие им модели принтеров (более полный
compatibility list можно найти на сайте
http://www.cs.wisc.edu/~ghost/doc/printer.htm). Если и там нужная вам
модель не нашлась, то можно попробовать взять драйвер от аналогичного
принтера (с более или менее похожим названием) и проверить его,
запустив, например, такую команду:
Если ничего подходящего найти не удалось, то можно поискать драйвер
среди gimp-print и IBM-Omni набора драйверов
(http://gimp-print.sourceforge.net,
http://www-124.ibm.com/developerworks/oss/linux/projects/omn i/).
Однако установка этих драйверов может потребовать перкомпиляцию
ghostscripta.
Устанавливаем систему печати и фильтр печати.
Если вы до сих пор не установили lprng и apsfilter, то самое время это
сделать сейчас. Запустите под root-ом демон печати lpd и с помощью
command-line скрипта /usr/share/apsfilter/SETUP настройте apsfilter.
Вам потребуется ответить на несколько вопросов (довольно простых -
если вы успешно прошли два предыдущих этапа) в результате чего будет
создана spool-directory и соответствующие пункт в /etc/printcap и
конфигурационные файлы apsfiler-а в директории
/etc/apsfilter/{spooler-name}/.
Apsfilter достаточно корректно работает с samba интерфейсом (если вы
правильно сконфигурировали его с помощью SETUP), но я предпочитаю
использовать скрипты собственного изготовления, наподобии приведенного
выше. Если вы решите последовать моему примеру, то вам нужно будет
удалить конфигурационный файл /etc/apsfilter/{spooler-name}/sambarc и
в /etc/printcap в нужном пункте исправить строчку lp=... , так как
показано выше. Поскольку в скрипте фигурируют пароли, то лучше
спрятать его от посторонних глаз в директории /var/spool/lp/AlexHP
(принадлежащей lp, и следовательно недоступной для других
пользователей), и поменять его owner-а на lp (chown lp
/var/spool/lp/AlexHP/Ustas_to_Alex), чтобы демон печати мог выполнить
его.
Теперь с помощью команды checkpc проверьте, что в файле printcap нет
синтаксических ошибок (checkpc -f автоматически пофиксит их), и можно
печатать тестовую страничку - lpr -PAlexHP test.ps. Если же напечатать
ее не удалось - то прежде, чем задавать вопросы в форумах - "А почему
у меня принтер не печатает?", попробуйте установить причину ошибки с
помощью команды lpq -PAlexHP -L (ключ -L означает, что выдана будет
максимально подробная информация - на несколько экранов!) - и, если
все же вам самому не удается справиться с проблемами, шлите эту
информацию на форумы вместе с /etc/printcap. Еще две утилитки, которые
вам понадобятся - lprm -P{printer-name}(удаление заданий из очереди
печати принтера -P) и lpc (command-line "Control Panel" для системы
печати - запускать ее следует из-под root-а, и первая команда, которую
вы должны использовать - help).
Чтобы приложения могли пользоваться системным spooler-ом (не все же
время в коммандной строке сидеть), им нужно указать команду, которая
отправляет задания на печать (lpr) - т.к. стандартного средства, с
помощью которого можно было бы установить, какая именно система печати
установлена, нет.
В Mozilla, например, это делается так - Print...->Properties и
редактируете Print Command. На этом процедуру конфигурирования Линукса
в качестве клиента для печати на самба-принтере можно считать
законченной. Обратная ситуация (т.е. Линукс в качестве принт-сервера),
хотя и более интересная с практической точки зрения, в данном тексте
не рассматривается, т.к. автор недостаточно владеет этим вопросом.
Любые замечания и дополнения приветствуются.