Jiří Benc, benc -zavináč- upir.cz

Tisk v *nixu, se zaměřením na GNU systémy

Úvod

Tisk v *nixových systémech je velmi obsáhlé téma, o kterém by se daly popsat stohy papíru. Rovněž zde panuje ohromné množství mýtů a zkreslených představ.

Tiskárny a tisk obecně jsou komplikovanou záležitostí a zdrojem mnoha obtíží snad na všech systémech. I přesto je nepopiratelné, že správné zkonfigurování a uvedení tiskárny do provozu je v *nixu složitější než v "klikacích" systémech typu MS Windows. Na druhou stranu, tato větší obtížnost je více než bohatě vyvážena flexibilitou a jednodušší správou, kterou konkurenční systémy nejsou schopny nabídnout. Obecně můžeme říci, že zatímco pro jednoduché využití tiskárny v nesíťovém prostředí je jednodušší nasadit systém MS Windows a pro malé sítě je použitelnost obou systémů srovnatelná, v případě větších sítí *nixové systémy jednoznačně vítězí. V rozsáhlých sítích jsou pak jedinou možnou alternativou.

Jak již bylo řečeno, v oblasti tisku na *nixu panuje řaduje pověr. Vycházejí zejména ze zastaralých informací - tiskové systémy se v současné době velmi progresivně rozvíjejí a za posledních několik let dosáhly značného pokroku, co se použitelnosti týče. Jedním z nejrozšířenějších mýtů je podpora malého spektra tiskáren. Stačí však nahlédnout do databáze podporovaných tiskáren (http://linuxprinting.org/database.html) a zjistíme, že pod různými volnými licencemi jsou dostupné ovladače pro více než 1000 modelů tiskáren (komerčně pak ještě mnohem více) a každou chvíli přibývají další.

Jakou tiskárnu tedy pro *nix zvolit? Nejlepší jsou tiskárny, které umí nativně PostScript (důvody viz dále). Naopak poměrně špatnou volbou jsou levné tiskárny s málo výkonným procesorem, které většinu operací nechávají na softwarovém ovladači (tzv. Windows-only tiskárny). Takovéto tiskárny nejsou podporovány buď vůbec, anebo jen velmi omezeně. V každém případě je dobré svou volbu zkonzultovat s již zmíněnou databází. Určitě neuškodí, pokud zvolíme výrobce, který sám vyvíjí ovladače pro Linux (např. HP pro některé své modely), či vývoj ovladačů podporuje uvolněním či poskytnutím svých specifikací (např. Epson).

Tisk z pohledu uživatele

Z historických důvodů existují dva na sobě nezávislé sady příkazů pro tisk a manipulaci s frontou úloh:

Systémy BSD:
příkaz lpr pro tisk (zařazení úlohy do tiskové fronty)
příkaz lpq pro prohlížení fronty
příkaz lprm pro mazání úloh z fronty
příkaz lpc pro ovládání tiskárny a fronty

Systémy System V:
příkaz lp pro tisk (zařazení do fronty)
příkaz lpstat pro prohlížení fronty
příkaz cancel pro mazání úloh z fronty

Kromě toho dnes nabízejí některé tiskové systémy další možnosti zařazování tiskových úloh či manipulace s frontou úloh (např. pomocí sdílených knihoven).

Filozofie tisku v Unixu

Nejdříve jen zjednodušeně

Zjednodušeně řečeno, jediný formát, který lze v *nixu tisknout, je PostScript. Všechy ostatní formáty na něj musí být nejdříve konvertovány (pomocí tzv. filtrů). Neznamená to, že nemůžete jako parametr příkazu lpr zadat obrázek. Znamená to jen, že tento obrázek je interně nejdříve zkonvertován na PostScript a teprve tento PostScript je poslán ke zpracování do fronty tiskových úloh. Složitějším aplikacím nezbývá nic jiného, než aby generovaly PostScript přímo (OpenOffice.org, Mozilla, atd.).

PostScriptový soubor se dále pomocí ovladačů tiskárny (což mohou být nejrůznější programy, včetně např. známého GhostScriptu, který slouží jako ovladač pro několik stovek tiskáren) převádí na jazyk, kterému tiskárna rozumí. Tato data jsou pak odeslána na komunikační port tiskárny.

Tento přístup má svou výhodu: není třeba, aby každý program, který chce umožnit tisk, uměl ovládat tiskárnu. Dokonce ani není třeba, aby existovalo jednotné rozhraní pro tisk. Stačí, když program dokáže vygenerovat PostScript a poslat ho na standardní vstup zvoleného jiného programu. (Tato výhoda je však zároveň nevýhodou. Podrobněji viz závěr.)

A teď trochu přesněji

O tisk se stará tzv. spooler, což je démon, jehož účelem je správa tiskové fronty. Spooler většinou zvládá i síťovou komunikaci, takž umožňuje tisknout na vzdálené tiskárně. Různých spoolerů existuje celá řada a ty nejrozšířenější a nejzajímavější budou popsány dále. Všechny však fungují na stejném principu (i když konkrétní pořadí jednotlivých kroků se může měnit, některé kroky mohou být vynechány či spojeny dohromady):

            job        =>  network   =>   queue   =>   filter   =>   printer
    (= data + options)

  1. Uživatel odešle tiskovou úlohu (job), což jsou data, volitelně jsou s nimi odeslány i údaje o nastavení tisku či způsobu, jakým se data mají tisknout (options). Data jsou většinou, ne však vždy, PostScript.
  2. Spooler zkopíruje tiskovou úlohu přes síť k tiskárně (obvykle úloha skončí v adresáři /var/spool/lpd či nějakém podobném).
  3. Spooler čeká, až bude tiskárna dostupná (volná).
  4. Tisková úloha je upravena podle nastavení (options), které si uživatel zvolil, a dále vedena sadou filtrů, které přeloží data do nativního jazyka tiskárny (který obyvkle není PostScript).
  5. Tisková úloha je dokončena. Provede se úklid, případně vyrozumění uživatele (zejména v případě chyby, většinou se vyrozumění posílá e-mailem).

Za zmínku stojí, že naprostá většina práce, kterou je potřeba při konfiguraci tiskárny udělat, je zajištění správné funkce v bodě 4. - tj. zejména nastavení filtrování tak, aby opravdu fungovalo.

Přehled tiskových systémů (spoolerů)

LPD (Line Printer Daemon)

LPD je původní tiskový démon z BSD Unixu. V současné době je zastaralý a nenabízí funkce, které bychom od moderního spooleru očekávali; jeho výhodou však je široká dostupnost (neexistuje snad žádný Unix-like systém, kde by nebyl LPD implementován). LPD je rovněž název síťového (TCP/IP) protokolu (RFC 1179). Tento protokol (ač rovněž zastaralý) je základem pro síťovou komunikaci mezi spoolery a podporují jej prakticky všechny ostatní tiskové systémy.

Démon LPD původně uměl obsluhovat pouze řádkové tiskárny. Podpora moderních tiskáren je řešena pomocí magických filtrů a front-endových programů. Správné nastavení LPD pro moderní tiskárnu je magie.

Zajímavostí je, že LPD existuje v několika implementacích, které jsou navzájem natolik promíchané (každá využívá část zdrojových kódů ostatních), že už dnes ani nelze říct, která implementace je která a která je vlastně ta původní. Proto zde ani neuvádím žádný odkaz.

Dnes už nemá smysl LPD používat. Tiskový systém LPRng (LPR next generation) nabízí mnohem více se zachováním zpětné kompatibility.

LPRng

http://www.lprng.org/

LPRng je novější rozšířená implementace LPD šířená pod GPL. Nabízí větší bezpečnost a více možností.

Protože však jde "pouze" o rozšířenou implementaci LPD, trpí i některými nedostatky původního LPD, jako je nutnost používání magických filtrů. Projekt LPRng se snaží tyto dopady co nejvíce eliminovat - základní sada filtrů je přímo součástí balíku, filtry jsou slušně dokumentovány.

Na rozdíl od původního lpr podporuje lpr z balíku LPRng nastavování vlastností tisku přímo z příkazového řádku. Lze tedy mít pro každou úlohu jiné nastavení. Rovněž je velmi zdokonalena podpora síťového tisku a jeho administrace (podpora automatického přepisování souboru /etc/printcap), proto je LPRng možno na rozdíl od LPD s úspěchem nasadit i u rozsáhlých sítí.

Dalšími zajímavými vlastnostmi LPRng je podpora jedné fronty pro více tiskáren (tj. více tiskáren se navenek tváří jako jedna), což je velmi důležité v některých podnikových sítích, podpora PGP a Kerberos. LPRng nemá na rozdíl od LPD žádné SUID binárky.

Pro svou kompatibilitu s LPD a své vlastnosti bylo LPRng dlouho standardním tiskovým systémem v mnoha linuxových distribucích (např. RedHat). Dnes však už prakticky všude ustoupilo před systémem CUPS.

GNUlpr

http://lpr.sourceforge.net/

GNUlpr byl projekt sponozorovaný firmou Hewlett-Packard jako součást VA Linuxu. Podpora před lety skončila a vývoj ustal.

GNUlpr je rozšířenou implementací LPD, podobně jako LPRng podporuje nastavení vlastností tisku z příkazového řádku programu lpr. Projekt dále obsahuje slušné množství navzájem provázaných utilit a knihoven. Jeho pravděpodobně nejzajímavější vlastností je však podpora souborů PostScript Printer Definition (PPD) - o významu těchto souborů viz dále.

CUPS (Common Unix Printing System)

http://www.cups.org/

CUPS je relativně mladý projekt, kladoucí si za cíl navhrnout kompletně nový tiskový systém nezatížený problémy LPD. Je vyvíjen pod GPL.

Lze říci, že se jedná asi o nejvhodnější tiskový systém pro většinu uživatelů - a to jak v nesíťovém prostředí, tak ve velkých sítích. Většina distribucí Linuxu jej používá jako standardní tiskový systém; ty ostatní jej nabízejí jako volbu.

CUPS důsledně odděluje tiskový back-end od front-endu. Front-endem mohou být také standardní příkazy pro tisk a pro manipulaci s tiskovou frontou, a to jak ve verzi BSD, tak ve verzi System V.

CUPS implementuje protokol IPP (Internet Printing Protocol - RFC 2910, RFC 2911 a další), který má být náhradou za zastaralý protokol LPD. Podporovány jsou ale také (i když ne všechny plně) protokoly LPD, SMB a AppSocket (JetDirect).

Výhody IPP jsou následující:

CUPS dále podporuje velké množství různých ovladačů (včetně možnosti využít PPD, a to i pro nepostscriptové tiskárny!), podporuje print classes (tj. více tiskáren se tváří jako jedna), pomocí broadcastů dokáže automaticky najít tiskárny (resp. CUPS servery) dostupné na síti a nainstalovat je (tj. zpřístupnit pro uživatele), navíc ho lze zkonfigurovat tak, aby se na tiskárny ve vzdálených sítích ptal nějakého jiného CUPS serveru (využití za směrovači či proxy bránami). Tiskárny na vzdálenějších sítích lze také nakonfigurovat ručně - přes webové rozhraní (http://localhost:631/admin) nebo přes příkazový řádek (příkaz lpadmin).

RLPR

http://truffula.com/rlpr/

Náhrada BSD příkazů lpr, lpq a lprm pod GPL (vyžaduje ale BSD-kompatibilního LPD démona; pro vzdálený tisk ho nepotřebuje lokálně).

PPR

http://ppr.trincoll.edu/

Spooler silně orientovaný na PostScript s dobrými schopnostmi účtování. Podporuje protokoly AppleTalk, SMB a LPD protokolů. Je šířen pod BSD-style licencí.

PDQ

http://pdq.sourceforge.net/

Zkratka PDQ znamená Print, Don't Queue. Jde o tiskový systém, který nepoužívá tiskového démona, tedy ani tiskovou frontu. Jeho výhodou je bezpečnost (vše se děje pod aktuálním uživatelem, žádná rootovská oprávnění nejsou potřeba, nedochází k zápisu mimo domovský adresář uživatele) a široké možnosti nastavení tiskárny. Nevýhodou je pomalost (celá tisková úloha se musí zpracovat dříve, než se začne tisknout, včetně případné rasterizace pro tiskárnu - což vede i k velkým nárokům na diskový prostor).

CPS

http://www.tww.cx/cps.php

Obskurní náhrada LPD napsaná v Perlu.

CEPS (Cisco Enterprise Print System)

http://ceps.sourceforge.net/

CEPS vytvořil správce tisku společnosti Cisco Systems. Je vytvořen pro specifické podmínky firmy CISCO a vhodný do obrovských organizací; jinde se jeho nasazení nevyplácí. Řeší problém distribuce souborů /etc/printcap (používá namísto nich sdílenou databázi). Šířen je pod GPL.

PostScript Printer Definition (PPD)

PPD jsou textové soubory, které definují vlastnosti, které tiskárna má, možná nastavení tiskárny a postscriptový kód, kterým se tato nastavení aktivují. PPD jsou specifikovány společností Adobe a dobře dokumentovány (specifikace, formát PDF).

Pro PostScriptové tiskárny jsou soubory PPD většinou poskytovány výrobcem (mnoho jich však lze stáhnout i ze stránek Adobe).

PPD jsou podporovány systémy CUPS a GNUlpr a také přímo některými aplikacemi (OpenOffice.org, Gimp). CUPS šel ještě dále a zavedl podporu PPD i pro nepostscriptové tiskárny. Podmínkou samozřejmě je, aby příslušný ovladač, který překládá PostScript do nativního jazyka tiskárny, vloženým direktivám rozuměl a uměl je přeložit.

Tiskové systémy podrobně

LPD

  1. Při bootu je spuštěn démon lpd, který spravuje tiskové fronty a čeká na připojení klientů.
  2. Pokud uživatel odešle tiskovou úlohu (přes příkaz lpr či nějakým front-endem), je přes síť kontaktován lpd démon a je mu předán datový soubor (obsahující data k vytištění) a řídící soubor (obsahující nastavení tisku).
  3. Jakmile je tiskárna dostupná, lpd se forkne, aby tiskovou úlohu obsloužil.
  4. Forknutá instance lpd spustí příslušné filtry (specifikované atributem if v /etc/printcap) a výsledná data pošle na tiskárnu.

Dnes je typicky filtr specifikovaný atributem if velká zrůdnost, která si zjistí MIME typ souboru a podle toho prožene data příslušným filtrem. Takto získaný PostScript je potom prohnán přes ovladač (GhostScript apod.), který vyprodukuje data v nativním jazyce tiskárny.

Možné filtry:

Samostatnou kapitolou je konfigurační soubor /etc/printcap. V něm je specifikováno nastavení tiskáren pro LPD. Obsahuje zejména následující položky: jméno spoolu (tj. tiskárny), přičemž lze použít i více jmen pro jednu položku; spoolovací adresář; cestu k zařízení (device), na které se bude tisknout; nastavení filtrů; nastavení titulní strany, maximální velikosti tiskové úlohy, účtování, atd. (viz man printcap).

Filtry se nastavují pomocí několika různých direktiv:
if: univerzální filtr, spouštěn znovu pro každou tiskovou úlohu;
of (output filter): spuštěn pouze jednou, použit pouze není-li specifikován filtr if;
a další filtry pro konkrétní formáty souborů: cf, df, gf,, nf, rf, tf, vf.

Filtry jsou spouštěny s různými parametry, které obsahují informace o filtrovaných datech. Nejvíce parametrů dostává filtr if.

Celé je to ale spojeno s několika problémy:

Soubor /etc/printcap je využíván i jinými tiskovými systémy. Např. LPRng jeho možnosti rozšiřuje přidáním množství dalších direktiv; CUPS tento soubor vytváří, ale nepoužívá.

GNUlpr

Nastavení tisku je možné předat pomocí parametru -o příkazu lpr (např. -o MediaType:Transparency), příp. lze použít ke specifikaci parametrů front-end GPR.

Nastavení je lpd serveru předáno v řídícím souboru jako rozšířené atributy. Jako magický filtr je použita modifikovaná verze rhs-printfilters, která dostane rozšířené atributy v proměnné prostředí a použije ppdfilt k jejich přidání k datům.

CUPS

Typická cesta tiskové úlohy:

    BSD/SysV commands => CUPS API => scheduler => filters => backends => printer

Plánovač (scheduler) přijímá tiskové úlohy, mimo to je však také administračním webovým rozhraním (podporuje přidávání/odebírání/konfigurování tiskárem, rušení úloh, startování/zastavování tiskáren; přeuspořádávání úloh zatím není implementováno).

Jako filtr je obvykle použit foomatic-rip (viz dále), ale lze použít i další podporované ovladače:

Backend může být IPP, LPD, SMB, JetDirect, Netatalk, USB, paralelní nebo sériové rozhraní (příp. lze na internetu najít i další backendy).

Použití a zpracování PPD v CUPS probíhá následujícím způsobem:

  1. Ke každé tiskové frontě je asociováno jedno PPD. CUPS server proparsuje PPD, aby získal informace o nastaveních dostupných uživateli.
  2. Klienti dostávají informace o možných nastaveních tisku od serveru "za běhu" (on the fly) jako seznam možných voleb (GUI klienti samozřejmě volby zobrazují jako grafické vybírací prvky). Z těchto voleb pak mohou např. vytvořit příkazový řádek pro lpr. Není tedy třeba, aby byly u klienta instalovány příslušné PPD, či aby jim klient rozuměl.
  3. Klient si tedy pouze vybere cílovou tiskárnu a pošle žádané nastavení společně s tiskovým souborem (většinou PostScript) CUPS serveru.
  4. Server na základě obsahu PPD a předaných voleb vloží správné příkazy do PostScriptu.
  5. PostScript je poté předán do RIP (Raster Imaging Process, tedy převod do rastrového formátu). To probíhá buď interně v postscriptové tiskárně, nebo v případě nepostscriptových tiskáren pomocí některého ovladače.
Specifikace PPD nepočítá s nepostscriptovými tiskárnami. Vývojáři CUPS ji proto rozšířili o příkazy, které říkají CUPSu, jak má soubor zpracovat (řádky "*cupsFilter ...").

Magické filtry

Projekt (databáze) Foomatic

http://linuxprinting.org/foomatic.html

Projekt Foomatic se snaží propojit svobodné ovladače s tiskovými systémy. Cílem je podpora všech typů svobodných ovladačů, podpora uživatelem nastavitelných voleb tisku a podpora většiny tiskových systémů (momentálně CUPS, LPRng, LPD, GNUlpr, PPR, PDQ, no spooler).

Foomatic dokáže vygenerovat vhodné PPD pro každý z modelů tiskáren, který je v databázi na LinuxPrinting.org. Tyto PPD jsou používány společně s filtrem foomatic-rip. Filtr foomatic-rip umí využít nejrůznější volně dostupné ovladače a umí spolupracovat s množstvím tiskových systémů. Dnes je ve většině distribucí použit jako základ pro podporu nepostscriptových tiskáren.

Foomatic používá PPD ke specifikování schopností tiskárny, a to i pro nepostscriptové tiskárny.

APS Filter

http://www.apsfilter.org/

Podporuje interní ovladače Ghostscriptu a různé varianty LPD (vč. LPRng). Distribuce používající LPRng většinou používají i apsfilter.

RHS-Printfilters

Starší systém filtrů vytvořený společností RedHat. VA Linux provedl některá vylepšení (podpora PPD) a zahrnul jej do GNUlpr.

Grafické front-endy

Prakticky ve všech programech, které umožňují tisk, lze nastavit příkaz, kterým bude tisk proveden. Kromě klasických lpr či lp lze zadat i některý z mnoha různých grafických front-endů. Nastavení tisku lze potom provést mnohem intuitivněji, navíc většina těchto front-endů zvládá i další pokročilé funkce (tisk více stran na stránku, náhled, atd.).

KDEPrint

http://printing.kde.org/

Součást KDE. Spouští se příkazem kprinter. Umí náhled tisku (vygeneruje PostScript a zobrazí ho pomocí programu KGhostView).

Součástí balíku KDEPrint je i program KJobViewer, který slouží k prohlížení a editaci tiskové fronty.

XPP (X Printing Panel)

http://cups.sourceforge.net/xpp/

Pouze pro CUPS. Umí tisk více stran na stránku, apod. Pokud je používán Foomatic, lze nastavit mnohem více věcí než zvládá samotné CUPS (vyvažování barev, zarovnání cartridge, atd.).

GPR

http://lpr.sourceforge.net/

Součást projektu GNUlpr. Umí však komunikovat i s klasickým LPD a s LPRng. Používá libppd, tedy umí zpracovávat PPD soubory. Dalšími funkcemi je tisk více stran na stránku, apod.

Tisk z pohledu Linuxového kernelu

Tiskárny můžeme v zásadě připojit na paralelní port, sériový port, nebo USB.

Nejjednodušší situace z pohledu kernelu je v případě tiskáren, které se připojují na sériový port.

Pro paralelní port existuje zařízení lp. U kernelů do verze 2.1.32 včetně existovala zařízení /dev/lp0, /dev/lp1, kde se číslo zařízení přidělovalo v závislosti na hardwarové I/O adrese. U novějších kernelů existuje ovladač parport, který je abstrakcí pro ovladače nižší úrovně (tedy ovladač lp je klientem parportu). Díky tomu lze sdílet porty mezi více zařízeními.

USB 1.1 je velmi dobře podporováno od pozdních kernelů řady 2.2. Existují dvě verze USB čipsetu (v závislosti na výrobci základní desky): UHCI (Intel, VIA) a OHCI.

USB 2.0 je podporováno od pozdějších kernelů řady 2.4.

Nevýhodou USB je paradoxně hotplug (tj. automatické alokování USB zařízení při připojení). Stejnou tiskárnu totiž reprezentuje pokaždé jiné zařízení v závislosti na pořadí zapnutí periferií (což je nepříjemné, pokud máme k systému připojených více tiskáren). CUPS to řeší tím, že si pamatuje výrobce, model a sériové číslo tiskárny (ve formě speciálního URI).

Problémy tisku na *nixech

Z uvedených skutečností vyplývají také některé problémy.

Odkazy

LinuxPrinting.org - http://linuxprinting.org/
The Linux Printing Usage HOWTO - http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html_single/Printing-Usage-HOWTO.html
The Printing HOWTO - http://www.ibiblio.org/pub/Linux/docs/HOWTO/other-formats/html_single/Printing-HOWTO.html
Tutorial on CUPS and Foomatic - http://www.linuxprinting.org//kpfeifle/LinuxKongress2002/Tutorial/