Печать в Linux HOWTO (Linux Printing HOWTO) : Как печатать на сетевой принтер

Next Previous Contents

## 11. Как печатать на сетевой принтер

Одним из свойств pdq и lpd является то что они поддерживают печать по сети на принтер, физически подключенный к другой машине. С помощью правильной комбинации фильтров и разнообразных утилит, вы можете печатать используя lpr на принтера во всех видах сетей.

## 11.1 На машину с Unix/lpd

Для того чтобы разрешить удаленным машинам печатать на ваш принтер используя протокол LPD, вы должны перечислить эти машины в файле /etc/hosts.equiv или /etc/hosts.lpd. (Заметим, что hosts.equiv имеет список машин несколько с другим эффектом; будьте уверены что вы знаете что вы делаете если перечисляете машины в этом файле). Вы можете разрешить только определенным пользователям на других машинах печатать на ваш принтер используя атрибут rs; читайте справочную страницу `lpd` для более детальной информации об этом.

### Используя `pdq`

Используя PDQ, вы определяете принтер с типом интерфейса "bsd-lpd". Этот интерфейс берет в качестве аргумента имя удаленного сервера и имя очереди печати; помощник определения принтера запросит у вас эти параметры.

### С помощью `lpd`

Для того чтобы печатать на другую машину вы должны сделать примерно такую запись в /etc/printcap:

> `

>     # Удаленный djet500
>     lp|dj|deskjet:\
>             :sd=/var/spool/lpd/dj:\
>             :rm=machine.out.there.com:\
>             :rp=printername:\
>             :lp=/dev/null:\
>             :sh:

> `

Заметим что все равно есть директория очереди на локальной машине обслуживаемая `lpd`. Если удаленная машина занята или отключена, то задание с локальной машины будет находиться в очереди до тех пор пока оно не сможет быть послано.

### С помощью `rlpr`

Вы также можете использовать rlpr для послания задания печати прямо в очередь удаленной машины без мороки с настройкой lpd для выполнения этой задачи. Это в большинстве случаев полезно в ситуациях когда вы печатаете на множество принтеров только время от времени. Из анонса rlpr:

Rlpr использует TCP/IP для посылки заданий печати на сервера с lpd, находящиеся где угодно в сети.

В отличии от lpr, он не требует чтобы удаленный принтер был явно известен машине с которой вы хотите печатать, (например в /etc/printcap) и таким образом является значительно белее гибким и требующим меньше администрирования.

rlpr может использоваться везде где мог бы использоваться традиционный lpr, и он является совместимым с традиционным BSD lpr.

Основная мощь rlpr заключается в удаленной печати откуда угодно куда угодно без учета как система на которую вы хотите печатать была настроена. Rlpr может работать как фильтр, как и традиционный lpr, так что клиенты выполняемые на удаленной машине такие как netscape, xemacs, и т.п., могут печатать на вашу локальную машину с небольшими усилиями.

Rlpr доступен с `Metalab`.

## 11.2 На принтер Win95, WinNT, LanManager, или Samba

Существует "Printing to Windows mini-HOWTO" в котором находится больше информации чем в данном документе.

### Используя PDQ

Нет предопределенного интерфейса smb, что я сознаю, но он может достаточно легко создан используя модель, заданную интерфейсом appletalk на базе пакета Netatalk. Некоторые люди создали его и выслали его для включения в дистрибутив!

Прочитайте раздел о Windows/LPD в следующих разделах данного документа для дополнительных советов как сделать данный драйвер.

### From LPD

Возможно перенаправить очередь lpd через программу `smbclient` (часть набора Samba) на основанный на TCP/IP сервис печати SMB. Samba включает скрипт называемый `smbprint`. Вкратце, вы помещаете конфигурационный файл для нужного принтера в его директорию спула, и устанавливаете для него скрипт `smbprint` как if-фильтр.

Запись в /etc/printcap выглядит примерно так:

> `

>     lp|remote-smbprinter:\
>         :lp=/dev/null:sh:\
>         :sd=/var/spool/lpd/lp:\
>         :if=/usr/local/sbin/smbprint:

> `

Вы должны прочитать документацию внутри скрипта `smbprint` для более детальной информации о настройке

Вы также можете использовать программу `smbclient` для посылки файла прямо на сервис печати SMB без вовлечения в этот процесс `lpd`. Смотрите справочные страницы.

## 11.3 На принтер NetWare

Набор программ ncpfs включает утилиту названную `nprint`, которая обеспечивает те же самые возможности как и `smbprint`, но для NetWare. Вы можете получить ncpfs с Metalab. Информация из записи в LSM для пакета версии 0.16:

> С помощью ncpfs вы можете монтировать тома вашего сервера netware под Linux. Вы также можете печатать в очереди печати netware и перенаправлять очереди печати netware на систему печати Linux. Вам необходимо ядро версии 1.2.x или 1.3.54 и выше. ncpfs НЕ работает с любыми ядрами 1.3.x ниже 1.3.54.

### From LPD

Для того чтобы заставить `nprint` работать через lpd, вам нужно написать маленький скрипт для печати потока стандартного ввода на принтер NetWare, и установить его как if-фильтр для очереди печати lpd. Вы получите что-то подобное этому:

> `

>     sub2|remote-NWprinter:\
>             :lp=/dev/null:sh:\
>             :sd=/var/spool/lpd/sub2:\
>             :if=/var/spool/lpd/nprint-script:

> `

`nprint-script` может выглядеть примерно так:

> `

>     #! /bin/sh
>     # Вы должны сначала попробовать вход как guest без пароля!
>     /usr/local/bin/nprint -S net -U name -P passwd -q printq-name -

> `

## 11.4 На принтер EtherTalk (Apple)

Пакет netatalk включает что-то подобное `nprint` и `smbclient`. Другие имеют документированные процедуры для печати на и с сетей Apple много лучше чем я представлял; Смотрите Linux Netatalk-HOWTO.

### Используя PDQ

PDQ включает в поставку объявление интерфейса, который называется "appletalk". Он использует пакет Netatalk для печати на подключенный к сети принтер Apple. Просто выберите этот интерфейс при использовании помощника добавления принтера в xpdq.

## 11.5 На HP или другой ethernet-принтер

Принтеры HP и некоторые другие принтера идут с интерфейсом на который вы можете печатать прямо, используя протокол lpd. Вы должны следовать инструкциям, которые идут с вашим принтером или его сетевым адаптером, но в главном такие принтера являются "работающим" lpd., и обеспечивают одну или более очередь на которые вы можете печатать. Например HP может работать с printcap подобным:

> `

>     lj-5|remote-hplj:\
>             :lp=/dev/null:sh:\
>             :sd=/var/spool/lpd/lj-5:\
>             :rm=printer.name.com:rp=raw:

> `

или используя аргументы REMOTE_HOST=printer.name.com и QUEUE=raw для PDQ интерфейса bsd-lpd.

Принтера HP Laserjet с интерфейсами Jet Direct iв общем поддерживают две встроенных очереди lpd -- "raw", которая принимает PCL (и возможно Postscript) и "text", которая принимает чистый ascii (и автоматически справляется с лестничным эффектом). Если у вас JetDirect Plus3 трех-портовый принтер, то очереди называются "raw1", "text2", и так далее.

Заметим, что компания ISS обнаружила набор атак denial of service (DoS), которые могут завесить интерфейсы HP Jetdirect. Большинство из них датируется началом осени 98.

В средах большого масштаба, особенно в больших средах где некоторые принтера не поддерживают PostScript, может быть полезно создать выделенный сервер печати на который все машины будут печатать и на котором все задания ghostscript будут запущены. Это позволит вам приостанавливать очереди печати или переорганизовывать их используя команды topq и lprm.

Это также позволяет вашей машине с Linux выступать как сервер печати для принтера, так что ваши пользователи сети смогут выполнять свои задания печати быстро и справляться с работой не ожидая пока принтер печатает какое-то другое задание посланное кем-то другим. Это также предполагается, если у вас есть старые HP Jetdirects, которые невозможно исправить; это уменьшает вероятность заклинивания принтеров.

Чтобы сделать это, установить очередь на вашей машине, которая указывает на оборудованный ethernet принтер HP LJ (как показано выше). Затем укажите для всех клиентов вашей LAN, чтобы они печатали на очередь печати Linux (например lj-5 как в вышеприведенном примере).

Некоторые сетевые принтера HP по всей видимости не нуждаются в установке страницы заголовка (banner page) посылаемой клиентом; вы можете отключить внутренне генерируемую страницу заголовка зайдя на принтер с помощью telnet, нажав два раза return, набрав "banner: 0" и затем "quit". Существуют другие настройки, которые вы можете изменить тем же способом; наберите "?" для просмотра списка установок.

Полный набор установок принтера может контролироваться с помощью программного обеспечения фирмы HP WebJet. Этот пакет запускается как демон и принимает http запросы на назначенном порту. Он обслуживает формы и Java апплеты, которые могут контролировать принтера HP, работающие в сети. Теоретически, он также может контролировать очереди печати Unix, но он делает это используя сервис rexec, который полностью незащищенным. Я не советую вам использовать это свойство данного пакета.

### На старые принтера HP

Некоторые принтера (и печатающие сетевые "черные ящики") поддерживают только никуда не годные маленькие непротокольные соединения включая чистые TCP соединения. Примечательными в этой категории являются ранние модели карт JetDirect (включая некоторые карты JetDirectEx). В основном для печати на принтер вы должны открыть соединение TCP на принтер на указанный порт (обычно 9100 или 9100, 9101 и 9102 для трех-портовых принтеров) и запихнуть свое задание печати в принтер. LPRng имеет встроенную поддержку для выдачи заданий печати на произвольные порты TCP, но при использовании BSD lpd это не так легко. Это может быть выполнено на Perl:

Интерфейс PDQ использующий netcat должен выглядеть примерно так:

> `

>     interface tcp-port-0.1 {

>        help "Это один из первых интерфейсов поддерживаемых стандартными
>              сетевыми принтерами и серверами печати. Устройство просто ожидает
>                      TCP-соединения на определенном порту, и посылает данные с любого
>                      соединения на принтер.\nЭтот интерфейс требует наличия программы
>                      netcat (\"nc\")."

>        required_args "REMOTE_HOST"

>        argument {
>           var = "REMOTE_HOST"
>           desc = "Удаленная машина"
>           help = "Имя или IP-адрес сервера печати."
>        }

>        argument {
>           var = "REMOTE_PORT"
>           def_value = "9100"
>           desc = "Удаленный порт"
>           help = "Это номер порта TCP сервера печати, на который должно посылаться
>                       задание. Большинство карт JetDirect, и их вариантов принимают
>                               задания на порту 9100 (или 9101 для порта номер 2, и т.п.)."
>        }

>        requires "nc"

>        # nc заканчивает работу после 45 секунд отсутствия сетевой активности:
>        # он не завершает работу после приема EOF как мы того желаем.
>        send_exec { cat $OUTPUT | nc -w 45 $REMOTE_HOST $REMOTE_PORT }

>     }

> `

В случае отсутствия этой программы, она может быть реализована другими способами, например на языке Perl, используя нижеприведенную программу. Или для большей производительности используйте программу netcat ("nc"), которая выполняет то же самое. Большинство дистрибутивов должны иметь эту программу в своем составе.

> `

>     #!/usr/bin/perl
>     # Спасибо Dan McLaughlin за написание оригинальной версии этого скрипта
>     # (А также Jim W. Jones за помощь мне при внесении исправлений ;)

>     $fileName = @ARGV[0];

>     open(IN,"$fileName") || die "Can't open file $fileName";

>     $dpi300     = "\x1B*t300R";
>     $dosCr      = "\x1B&k3G";
>     $ends = "\x0A";

>     $port =  9100 unless $port;
>     $them = "bach.sr.hp.com" unless $them;

>     $AF_INET = 2;
>     $SOCK_STREAM = 1;
>     $SIG{'INT'} = 'dokill';
>     $sockaddr = 'S n a4 x8';

>     chop($hostname = `hostname`);
>     ($name,$aliases,$proto) = getprotobyname('tcp');
>     ($name,$aliases,$port) = getservbyname($port,'tcp')
>         unless $port =~ /^\d+$/;;
>     ($name,$aliases,$type,$len,$thisaddr) =
>             gethostbyname($hostname);
>     ($name,$aliases,$type,$len,$thataddr) = gethostbyname($them);
>     $this = pack($sockaddr, $AF_INET, 0, $thisaddr);
>     $that = pack($sockaddr, $AF_INET, $port, $thataddr);

>     if (socket(S, $AF_INET, $SOCK_STREAM, $proto)) {
>     #    print "socket ok\n";
>     }
>     else {
>         die $!;
>     }
>     # Задать адрес сокету.
>     if (bind(S, $this)) {
>     #    print "bind ok\n";
>     }
>     else {
>         die $!;
>     }

>     # Вызвать сервер.

>     if (connect(S,$that)) {
>     #    print "connect ok\n";
>     }
>     else {
>         die $!;
>     }

>     # Установить буферизацию для сокета.

>     select(S); $| = 1; select(STDOUT);

>     #    print S "@PJL ECHO Hi $hostname! $ends";
>     #    print S "@PJL OPMSG DISPLAY=\"Job $whoami\" $ends";
>     #    print S $dpi300;

>     # Избежать блокировки при fork.

>     if($child = fork) {
>         print S $dosCr;
>         print S $TimesNewR;

>         while (<IN>) {
>             print S;
>         }
>         sleep 3;
>         do dokill();
>     } else {
>         while(<S>) {
>             print;
>         }
>     }

>     sub dokill {
>         kill 9,$child if $child;
>     }

> `

## 11.6 Запуск if для удаленных принтеров со старыми LPD

Одна странность старых версий lpd в том что if не запускается для удаленных принтеров. (Версии после 0.43 или примерно такой имеют изменения внесенные на FreeBSD, так что они всегда работают). Если вам нужно выполнить if, вы можете сделать это установив двойную очередь и перенаправляя задание. Как пример рассмотри такой printcap:

> `

>     lj-5:remote-hplj:\
>             :lp=/dev/null:sh:\
>             :sd=/var/spool/lpd/lj-5:\
>             :if=/usr/lib/lpd/filter-lj-5:
>     lj-5-remote:lp=/dev/null:sh:rm=printer.name.com:\
>             :rp=raw:sd=/var/spool/lpd/lj-5-raw:

> `

в свете этого скрипт `filter-lj-5` будет выглядеть так:

> `

>     #!/bin/sh
>     gs <options> -q -dSAFER -sOutputFile=- - | \
>             lpr -Plj-5-remote -U$5

> `

Опция -U lpr работает только если lpr запущен как демон, и она правильно устанавливает имя имя автора задания при его перенаправлении. Вы должны вероятно использовать более надежный метод получения имени пользователя, так как в некоторых случаях оно не является пятым аргументом. Смотрите справочную станицу printcap.

## 11.7 Из Windows

Печать из под клиента Windows (или OS/2) на сервер Linux прямо поддерживается через SMB используя пакет SAMBA, который также поддерживает разделение вашей файловой системы Linux с клиентами Windows.

Samba включает в себя довольно полную документацию. Вы можете либо настроить magic-фильтр на машине с Linux и печатать на нее в формате PostScript или установить специфичные для принтера драйвера на всех машинах с Windows и обрабатывать очередь без фильтрации. Полагаясь на драйвера Windows вы можете в некоторых случаях получить более качественный вывод, но это дает больше административной нервотрепки если у вас много машин с Windows. Так что сначала попробуйте PostScript.

Используя PDQ, вы должны настроить Samba для запуска команды pdq с соответствующими аргументами вместо команды lpr, которая выполняется по умолчанию. Я верю, что Samba будет запускать pdq с правами соответствующего пользователя, так что он должен работать нормально. Существует несколько настроек Samba, которые вы должны выставить для правильной работы:

printcap

  этот параметр должен указывать на "фальшивый" файл, в котором вы должны перечислить доступные принтера. Все что нужно указать, это короткие и длинные сервера для каждого из принтера, один на каждую строку:

  > `

  >     lp1|Printer One
  >     lp2|Printer Two
  >     lp3|Printer Three

  > `

  Короткое имя будет использоваться как имя принтера в команде печати:

print command

  Этот параметр должен быть установлен во что-нибудь подобное следующему `pdq -P %p %s ; rm %s`.

lprm command

  Для этого параметра пока нет хорошего значения. Буферизованные задания PDQ будут сниматься после истечения времени, так что если принтер не работает, то все нормально. Но если вы просто решили отменить свое намерение, то вы можете использовать программу xpdq для отмены заданий, но это неприменимо для Windows. Просто вствьте сюда ничего не делающую команду, такую как true. Если вы используете lpd или lprng в качестве основы, то соответствующая команда lprm должна нормально работать. Я не уверен, что Samba может идентифицировать номер задания в очереди lpr для запущенных pdq заданий.

lpq command

  Также PDQ не предоставаляет хорошего значения, которое можно поместить здесь. Распределенные системы не предлагают нормального решения для того, чтобы видеть очередь печати, но основанные на samba сервера должны иметь достойную схему. если вы используете lpd или lprng как основу, то соответствующая команда lpq c должна работать; вы просто не сможете увидеть задания, до того, как они будут отфильтрованы PDQ.

## 11.8 С Apple.

Netatalk поддерживает печать с клиентов Apple через EtherTalk. Смотрите Страницу Netatalk HOWTO для более детальной информации.

## 11.9 Из под Netware

Пакет ncpfs включает демона называемого pserver, который может быть использован для обеспечения сервиса очередей печати NetWare. Как я понял эта система требует основанную на Bindery систему NetWare, т.е. 2.x, 3.x, или 4.x с разрешенным доступом к bindery.

Для более детальной информации о ncpfs и ее программе pserver смотрите FTP сервер ncpfs FTP.

Next Previous Contents