Сетевой принтер через lpd: Настройка, печать


Когда я впервые пытался настроить печать на сетевой принтер из FreeBSD, я с удивлением обнаружил, что советы, которыми наводнена Всемирная Паутина мне не подходят. Handbook мне тоже не помог. Возможно, авторы этих советов пользовались старой версией lpd. Приведённая здесь информация актуальна для FreeBSD от 5.3 до 6.0, но возможно она пригодится и пользователям Linux и других UNIX.

На этой же странице вы найдёте много информации, актуальной не только для сетевых принтеров.

Предмет
Мы имеем сетевой принтер HP. Язык принтера — PCL. IP адрес — 192.168.1.4.

Требуется организовать печать на этом принтере из-под FreeBSD.

Будем решать её с помощью демона lpd.

Настраиваем printcap

Первым делом, пишем в /etc/printcap нечто вроде:

lp|text:\
:sh:sd=/var/spool/lpd:\
:if=/usr/share/examples/printing/ifhp:\
:lp=9100@192.168.1.4:rm=192.168.1.4:

Мы создали принтер с именем lp. Это имя используется по умолчанию всеми программами печати.

Обратите внимание, на параметр lp. Он задаёт адрес принтера и порт. Многие источники настаивают на том, что для сетевых принтеров этот параметр указывать не надо, но на самом деле он является обязательными.

Настраиваем фильтр
Эта часть заметки подойдёт для любого (не только сетевого) принтера.

Я использую фильтр, поставляемый с FreeBSD, лишь слегка его подправив.

#!/bin/sh
#
# фильтр для печати на HP принтере PostScript и plain-text (koi8) файлов
#
# Концы строк будут в стиле UNIX
printf "\033&k2G" || exit 2
#
# читаем первую стоку
read first_line
# выделяем первые два символа
first_two_chars=`expr "$first_line" : '\(..\)'`
# проверяем, с чем мы имеем дело
if test "$first_two_chars" = "%!" -o "$first_two_chars" = "%P"
then
# печатаем PS и PDF
(echo "$first_line" && cat) | \
/usr/local/bin/gs -dSAFER \
-dNOPAUSE \
-q \
-sDEVICE=djet500 \
-sOutputFile=- — && exit 0
else
# печатаем обычный текст, конвертируя его
printf "\033(3R" &&
echo "$first_line" &&
iconv -f KOI8-R -t 866 &&
printf "\f" &&
exit 0
fi
exit 2

В «родном» фильтре допущена небольшая неаккуратность: при печати PostScript-файлов на вход gv не попадает первая строка файла. Для PostScript это оказывается не критично и всё работает, но для PDF это смертельно. Поправив эту неточность мы сразу получаем возможность печатать PDF-файлы.

Этот фильтр автоматически различает PostScript и PDF. Всё, что не похоже не PostScript и PDF печатается, как обычный текст.

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

Для других нужд я создаю другие принтеры (записи с другими именами в /etc/printcap) и другие фильтры. Вот фильтр для печати PNG-картинок с разрешением 150dpi:

#!/bin/sh
/usr/local/bin/convert -density 150 png:- pcl:-

Запускаем демон
Теперь можно запускать демон печати lpd. Для этого достаточно ввести с командной строки его имя.

У lpd есть очень полезный ключ -s, который запрещает серверу принимать задания с удалённых машин. Ключ -W не заменим, если вы организуете принт-сервер, для многих пользователей, он позволяет подключаться c портов с номерами больше 1024. Без этого ключа lpd будет обслуживать соединения только с портов не выше 1024 и скорее всего не примет задания от клиентов. Кстати, если вы позволяете другим хостам пользоваться вашим принтером, то их имена (или IP-адреса) следует упомянуть в /etc/hosts.lpd.

Чтобы сервер запускался автоматически, добавьте в /etc/rc.conf:

lpd_enable="YES"

Чтобы передать серверу дополнительные ключи, добавьте туда же:

lpd_flags="-s"

Печатаем
После запуска сервера вы можете начать печатать:

lpr file.txt

lpr file.ps

Имя принтера можно указать явно:

lpr -Ppng file.png

На этом этапе возможно одно единственное недоразумение: сообщение

unable to get official name for local machine

В этом нет ничего страшного, просто машина не может разрешить собственное имя. Посмотрите имя вашей машины, например командой hostname и добавьте его в файл /etc/hosts. Или наоборот — установите имя хоста, согласно настройкам вашего DNS-сервера.
Исправляем неполадки

Если печать не работает.
• Проверьте, правильно ли установлены права на скрипты-фильтры.
• Укажите полные пути ко всем утилитам, используемым в фильтрах.
• Проверьте, существует ли директория, указанная в параметре sd и возможна ли в неё запись.
• Если вы завели не один принтер, проверьте, не используют ли разные принтеры одну и туже директорию для спуллинга (sd).
• Укажите параметр lf=/путь/к/журналу/ошибок. Возможно журнал вам поможет.

Тонкости настройки
Вы наверно обратили внимание на команду printf "\033(3R" в моём фильтре. Это управляющая последовательность, говорящая принтеру, что на него будет подаваться русский текст в кодировке CP866. Ещё одна полезная последовательность, о которой стоит упомянуть, задаёт размер шрифта: \033(s%dH, где на месте %d должно быть число строк на дюйм. Шрифт масштабируется пропорционально этому значению. Исчерпывающую информацию по управляющим последовательностям можно найти здесь http://lprng.sourceforge.net/DISTRIB/RESOURCES/DOCS/.

BUGS (недостатки предложенного фильтра)
Предложенный мною здесь фильтр хорош тем, что распознаёт PostScript и PDF, и автоматически перекодирует текст и подстраивает принтер, но через этот фильтр можно печатать только русский текст в кодировке koi8-r и PostScript. При попытке напечатать, скажем, уже готовый PCL-код, мой фильтр выполнит перекодировку и исказит данные.

Более того, команды, используемые в фильтре, не равнодушны к нулевому байту (\000). Поэтому, даже если вы уберёте перекодировку, картинка в формате PCL скорее всего не будет корректно напечатана. Этой болезнью страдает и «родной» пример скрипта.

Так что, если вы хотите печатать нечто нетривиальное, то вам придётся существенно изменить фильтр и скорее всего — переписать его на более подходящем языке, чем shell.


Комментарии запрещены.




Статистика