Dieser Abschnitt beschreibt den Einsatz von Filtern für das Drucken speziell formatierter Seiten oder von Deckblättern, das Drucken über ein Netzwerk sowie die Beschränkung und Verrechnung der Druckernutzung.
Obwohl LPD Netzwerkprotokolle, Warteschlangen, Zugriffskontrollen und andere für das Drucken wichtige Aspekte prinzipiell unterstützt, passiert ein Großteil der wirklichen Arbeit in den sogenannten Filtern. Dabei handelt es sich um Programme, die direkt mit einem Drucker kommunizieren und deren Gerätespezifika und spezielle Anforderungen erfüllen. Im einfachsten Fall installiert man nur einen reinen Textfilter, der mit beinahe allen Druckern funktionieren sollte. (Lesen Sie dazu auch den Abschnitt Den Text-Filter installieren.)
Um die erweiterten Fähigkeiten von Druckern auch einsetzen zu können, sollten Sie verstehen, wie Filter arbeiten, da diese für die Bereitstellung dieser Funktionen zuständig sind. Die schlechte Nachricht ist, dass Sie diese Filter bereitstellen müssen. Die gute Nachricht ist allerdings, dass diese in der Regel bereits vorhanden sind. Ist dies nicht der Fall, können Sie einen Filter meist relativ einfach selbst erstellen.
Der Filter /usr/libexec/lpr/lpf wird bereits mit FreeBSD geliefert. Er kümmert sich um die korrekte Behandlung von gelöschten Zeichen (das sogenannte Backspacing), um im Text enthaltene Tabulatoren, sowie um die Verrechnung von Druckaufträgen. Das ist aber auch alles, was dieser Filter kann. Zusätzliche Filter und für die Funktion von Filtern nötige Komponenten finden sich aber in der FreeBSD Ports-Sammlung.
Dieser Abschnitt behandelt folgende Themen:
Der Abschnitt Die Funktionsweise von Filtern versucht, einen Überblick über die Rolle von Filtern innerhalb des Druckprozesses zu geben. Sie sollten diesen Abschnitt lesen, damit Sie verstehen, was “unter der Haube” passiert, wenn LPD einen Filter verwendet. Dieses Wissen wird Ihnen dabei helfen, Probleme, die bei Installation von Filtern für verschiedene Drucker entstehen können, vorauszusehen und zu beheben.
LPD geht davon aus, dass jeder Drucker in der Lage ist, normalen Text zu drucken. Für PostScript®- (oder andere sprachbasierte) Drucker stellt dies allerdings ein Problem dar, da diese nicht in der Lage sind, normalen Text direkt zu drucken. Der Abschnitt Normalen Text auf PostScript-Druckern drucken beschreibt, wie Sie dieses Problem lösen können. Besitzen Sie einen PostScript-Drucker, sollten Sie diesen Abschnitt lesen.
PostScript ist ein populäres Ausgabeformat, das von vielen Programmen unterstützt wird. Es ist sogar möglich, PostScript-Code direkt zu schreiben. Leider sind PostScript-Drucker in der Regel relativ teuer. Der Abschnitt PostScript auf Nicht-PostScript-Druckern emulieren beschreibt, wie Sie einen Textfilter anpassen müssen, um PostScript-Daten auf einem nicht-PostScript-fähigen Drucker auszugeben. Haben Sie keinen PostScript-Drucker, sollten Sie insbesondere diesen Abschnitt lesen.
Der Abschnitt Konvertierungsfilter
beschreibt eine Möglichkeit zur automatischen Konvertierung verschiedener
Dateiformate in ein von Ihrem Drucker unterstütztes Format. Nachdem Sie diesen
Abschnitt gelesen haben, werden Sie in der Lage sein, Ihren Drucker so zu konfigurieren,
dass Sie durch die Eingabe von lpr -t
troff-Daten, von lpr -d
TeX-DVI-Daten, oder von lpr -v
Rasterbilddaten drucken
können. Daher sollten Sie diesen Abschnitt auf jeden Fall lesen.
Im Abschnitt Ausgabefilter wird eine nur selten genutzte Eigenschaft von LPD, die sogenannten Ausgabefilter, beschrieben. Wenn Sie keine Deckblätter drucken müssen, können Sie diesen Abschnitt überspringen.
Der Abschnitt lpf: Ein Textfilter beschreibt lpf, einen kompletten, wenn auch einfachen Textfilter für Zeilendrucker (oder auch Laserdrucker, die sich analog verhalten), der bereits mit FreeBSD geliefert wird. Wenn Sie nur am Ausdruck von reinem Text interessiert sind, oder wenn Ihr Drucker nur “Schrott” produziert, wenn er auf Backspace-Zeichen trifft, sollten Sie sich lpf näher ansehen.
Anmerkung: Eine Kopie der verschiedenen Skripte finden Sie im Verzeichnis /usr/share/examples/printing.
Bei einem Filter handelt es sich um ein ausführbares Programm, das von LPD gestartet wird, um den geräteabhängigen Teil der Kommunikation mit einem Drucker zu übernehmen.
Wenn LPD eine Datei über einen Druckauftrag drucken will, startet es ein Filterprogramm. Danach setzt es die Standardeingabe des Filters auf die zu druckende Datei, die Standardausgabe auf den Drucker und die Standardfehlerausgabe auf /dev/console (Voreinstellung) oder auf die über die Option lf in /etc/printcap festgelegte Datei.
Welcher Filter von LPD mit welchen Argumenten geladen wird,
wird in der Datei /etc/printcap oder durch die Argumente, die
der Anwender lpr(1) auf der
Kommandozeile übergibt, festgelegt. Gibt der Anwender beispielsweise lpr -t
ein, startet LPD über die tf-Fähigkeit den
troff-Filter für den gewünschten Drucker. Wollen Sie hingegen normalen Text
drucken, wird der if-Filter gestartet. (Für Ausnahmen von
diesem Vorgehen lesen Sie bitte den Abschnitt Ausgabefilter.)
Es gibt drei Arten von Filtern, die Sie in /etc/printcap angeben können:
Textfilter (die in der LPD-Dokumentation als input filter bezeichnet werden) sind für den Druck von normalem Text zuständig. Es handelt sich dabei um eine Art Standardfilter, da LPD von jedem Drucker erwartet, dass er normalen Text drucken kann. Aufgabe des Textfilters ist es, sicherzustellen, dass gelöschte Zeichen (Backspaces), Tabulatoren und andere Sonderzeichen Ihren Drucker nicht verwirren. Falls Sie für die Nutzung eines Druckers bezahlen müssen, kann der Textfilter über die Anzahl der gedruckten Zeilen auch die Anzahl der von Ihnen gedruckten Seiten ermitteln. Der Textfilter wird mit folgenden Argumenten gestartet:
filter-name [-c] -w width -l length -i indent -n login -h host acct-file
Die einzelnen Argumente haben folgende Bedeutung:
-c
Notwendig, wenn lpr -l
verwendet
wird.
Der Wert der in /etc/printcap festgelegten Option pw (page width). In der Voreinstellung ist dieser Wert auf 132 gesetzt.
Der Wert der pl-Fähigkeit (page length), Voreinstellung 66.
Der durch lpr -i
festgelegte
Einzug, Voreinstellung 0.
Der Name des Benutzers, der die Datei druckt.
Der Rechner, auf dem der Druckauftrag gestartet wurde.
Der Name der Verrechnungsdatei, in der die Ergebnisse der af-Fähigkeit gespeichert werden.
Ein Konvertierungsfilter konvertiert verschiedene Dateiformate in ein Format, das Ihr Drucker auf Papier ausgeben kann. So kann etwa der ditroff-Schriftsatz nicht direkt gedruckt werden, daher müssen Sie einen Konvertierungsfilter installieren, um diese Daten in ein Format zu bringen, das Ihr Drucker verarbeiten und drucken kann. Der Abschnitt Konvertierungsfilter enthält ausführliche Informationen zu diesen Filtern. Konvertierungsfilter können auch zur Verrechnung verwendet werden. Sie werden mit folgenden Argumenten gestartet:
filter-name -x pixel-width -y pixel-height -n login -h host acct-file
pixel-width ist der Wert der px-Fähigkeit (Voreinstellung 0), während pixel-height dem Wert der py-Fähigkeit (Voreinstellung ebenfalls 0) entspricht.
Ausgabefilter werden nur verwendet, wenn keine Textfilter vorhanden sind oder wenn Deckblätter benötigt werden. Der Abschnitt Ausgabefilter enthält weitere Informationen. Ausgabefilter unterstützen nur zwei Argumente:
filter-name -w width -l length
Beide Argumente entsprechen den Optionen -w
und -l
der Textfilter.
Alle Filter sollten mit folgenden Rückgabewerten (Exitcodes) beendet werden:
Der Filter hat die Datei erfolgreich gedruckt.
Der Filter war nicht in der Lage, die Datei zu drucken und meldet diesen Exitcode an LPD, um die Datei erneut zu drucken. LPD startet daraufhin den Filter erneut.
Der Filter war nicht in der Lage, die Datei zu drucken. Bei diesem Exitcode soll LPD aber nicht versuchen, die Datei erneut zu drucken, sondern den Druckauftrag verwerfen.
/usr/libexec/lpr/lpf, der mit FreeBSD gelieferte Textfilter, nutzt die Argumente page width und page length, um festzulegen, wann ein Seitenumbruch (form feed) gesendet werden soll sowie zur Verrechnung von Druckaufträgen. Dazu werden der Benutzername, der für den Druckauftrag verwendete Rechner sowie die Verrechnungsdatei ausgewertet, um die entsprechenden Einträge zu erstellen.
Wenn Sie auf der Suche nach Filtern sind, achten Sie darauf, dass diese LPD-kompatibel sind. Dazu müssen diese die oben beschriebenen Argumente unterstützen. Wenn Sie planen, Ihre Filter selbst zu erstellen, müssen diese ebenfalls die gleichen Argumente und Exitcodes unterstützen.
Sie sind der alleinige Benutzer Ihres Computers und Ihres PostScript-Druckers und Sie sind sich sicher, dass Sie niemals normalen Text an Ihren Drucker senden werden? Außerdem werden Sie niemals ein Programm verwenden, um normalen Text auszudrucken? Nur wenn dies alles zutrifft, können Sie diesen Abschnitt überspringen.
Wollen Sie allerdings sowohl PostScript als auch normalen Text drucken, müssen Sie Ihren Drucker zuvor entsprechend konfigurieren. Dazu muss Ihr Textfilter in der Lage sein, zu unterscheiden, ob es sich bei einem ankommenden Druckauftrag um normalen Text oder um PostScript-Daten handelt. Jeder PostScript-Druckauftrag muss mit den Zeichen %! beginnen (sehen Sie in Ihrem Druckerhandbuch nach, ob Ihr Drucker weitere Sprachen unterstützt). Sind dies die beiden ersten Zeichen eines Druckauftrages, so handelt es sich um PostScript-Daten, die direkt gedruckt werden können. Fehlen diese Zeichen allerdings, muss der Textfilter den Inhalt der Datei nach PostScript konvertieren, bevor die Datei gedruckt werden kann.
Wie funktioniert diese Unterscheidung?
Haben Sie einen seriellen Drucker, können Sie lprps installieren. lprps ist ein PostScript-Druckerfilter, der eine Zweiwegekommunikation mit einem Drucker ermöglicht. Er aktualisiert die Druckerstatusdatei mit Protokollinformationen des Druckers. Dadurch sind Anwender und Administratoren in der Lage, den genauen Zustand des Druckers zu prüfen (durch Meldungen wie “toner low” oder “paper jam”). Wichtiger ist allerdings, dass lprps psif enthält, ein Programm, das feststellen kann, ob ein ankommender Druckauftrag normalen Text enthält. Ist dies der Fall, wird textps (das ebenfalls mit lprps geliefert wird) aufgerufen und die Datei nach PostScript konvertiert. Danach kann lprps die Datei an den Drucker senden.
lprps ist in der FreeBSD Ports-Sammlung enthalten. Je nach der von Ihnen verwendeten Papiergröße installieren Sie dazu den Port print/lprps-a4 oder print/lprps-letter. Nach der Installation müssen Sie nur noch den Pfad zum Programm psif angeben, das als Teil von lprps installiert wird. Haben Sie lprps über die Ports-Sammlung installiert, fügen Sie folgende Zeile in den Eintrag Ihres PostScript-Druckers in /etc/printcap ein:
:if=/usr/local/libexec/psif:
Zusätzlich sollten Sie die rw-Fähigkeit aktivieren, um LPD im Schreib- und Lesemodus zu öffnen.
Haben Sie hingegen einen parallelen PostScript-Drucker, was eine Zweiwegekommunikation mit Ihrem Drucker (auf die lprps angewiesen ist) unmöglich macht, können Sie das folgende Shell-Skript verwenden:
#!/bin/sh # # psif - Drucke PostScript oder normalen Text auf einem PostScript-Drucker # Script-Version; das ist NICHT die mit lprps gelieferte Version! # Installiert unter: /usr/local/libexec/psif # IFS="" read -r first_line first_two_chars=`expr "$first_line" : '\(..\)'` if [ "$first_two_chars" = "%!" ]; then # # PostScript - einfach drucken. # echo "$first_line" && cat && printf "\004" && exit 0 exit 2 else # # Normaler Text - zuerst konvertieren, dann drucken. # ( echo "$first_line"; cat ) | /usr/local/bin/textps && printf "\004" && exit 0 exit 2 fi
Für dieses Skript wurde textps als seperates Programm installiert, um normalen Text nach PostScript zu konvertieren. Sie können aber auch jeden anderen Text-nach-PostScript-Konverter verwenden. Die FreeBSD Ports-Sammlung enthält mit a2ps ein umfangreiches Programm zur Konvertierung von normalem Text nach PostScript.
Bei PostScript handelt es sich um den de facto-Standard für hochwertigen Schriftsatz und Druck. Leider ist PostScript aber auch ein teurer Standard. Glücklicherweise hat Aladdin Enterprises daher eine freie PostScript-ähnliche Implementierung namens Ghostscript entwickelt, die auch unter FreeBSD lauffähig ist. Ghostscript kann fast jede PostScript-Datei lesen und auf den verschiedensten Geräten ausgeben, darunter auch auf vielen Nicht-PostScript-Druckern. Durch die Installation von Ghostscript und die Nutzung eines speziellen Textfilters erreichen Sie, dass sich Ihr Nicht-PostScript-Drucker wie ein echter PostScript-Drucker verhält.
Ghostscript ist in verschiedenen Versionen in der FreeBSD Ports-Sammlung enhalten, die am häfigsten verwendete Version ist print/ghostscript-gpl.
Um PostScript zu emulieren, muss der Textfilter erkennen, ob er eine PostScript-Datei drucken soll. Ist dies nicht der Fall, wird die Datei direkt an den Drucker geschickt. Anderenfalls wird die Datei an Ghostscript übergeben, das die Datei in ein Format konvertiert, das Ihr Drucker versteht.
Dazu ein Beispiel. Das folgende Skript ist ein Textfilter für den Drucker DeskJet
500 von Hewlett Packard. Nutzen Sie einen anderen Drucker, müssen Sie die Option
-sDEVICE
beim Aufruf von gs
(Ghostscript) entsprechend anpassen. Eine Liste der von Ghostscript unterstützten Geräte erhalten Sie durch die
Eingabe von gs -h
auf der
Kommandozeile.
#!/bin/sh # # ifhp - Ghostscript-emuliertes PostScript auf einem HP DeskJet 500 drucken # Installiert unter: /usr/local/libexec/ifhp # # LF als CR+LF behandeln (um einen "Treppeneffekt" auf HP/PCL-Drucker # zu vermeiden) # printf "\033&k2G" || exit 2 # # Lies die ersten zwei Zeichen der Datei # IFS="" read -r first_line first_two_chars=`expr "$first_line" : '\(..\)'` if [ "$first_two_chars" = "%!" ]; then # # Oh. Es ist PostScript; mit Ghostscript konvertieren, danach drucken. # /usr/local/bin/gs -dSAFER -dNOPAUSE -q -sDEVICE=djet500 \ -sOutputFile=- - && exit 0 else # # Normaler Text oder HP/PCL, einfach direkt drucken. Ans Ende setzen wir # einen Seitenumbruch (also ein Form Feed), damit auch die letzte Seite # ausgeworfen wird. # echo "$first_line" && cat && printf "\033&l0H" && exit 0 fi exit 2
Zuletzt müssen Sie LPD noch durch die if-Fähigkeit über den neuen Filter informieren:
:if=/usr/local/libexec/ifhp:
Das ist alles. Ab sofort sollte sowohl ein lpr normaler.text als auch ein lpr wasauchimmer.ps funktionieren und beide Dateien sollten problemlos gedruckt werden.
Nachdem Sie Ihren Drucker wie unter Einfache Drucker-Konfiguration eingerichtet haben, wollen Sie wahrscheinlich einige Konvertierungsfilter installieren, damit Sie (abgesehen von ASCII-Text) auch Ihre Lieblings-Dateiformate drucken können.
Konvertierungsfilter erleichtern das Drucken von verschiedenen Dateiformaten. Nehmen wir beispielsweise an, dass Sie sehr viel mit dem TeX-Satzsystem arbeiten und über einen PostScript-Drucker verfügen. Eine vom TeX-System erzeugte DVI-Datei kann erst dann gedruckt werden, nachdem diese nach PostScript konvertiert wurde. Dazu geben Sie Folgendes ein:
% dvips seaweed-analysis.dvi % lpr seaweed-analysis.ps
Haben Sie einen Konvertierungsfilter für DVI-Dateien installiert, können Sie die manuelle Konvertierung überspringen, da dies nun LPD für Sie erledigt. Wollen Sie eine DVI-Datei drucken, geben Sie nur noch den folgenden Befehl ein:
% lpr -d
seaweed-analysis.dvi
Durch die Verwendung der Option -d
wurde LPD angewiesen, unsere DVI-Datei vor dem Druck zu konvertieren.
Der Abschnitt Formatierungs-
und Konvertierungsoptionen beschreibt die dabei möglichen Optionen.
Für jede Konvertierungsoption, die Ihr Drucker unterstützen soll, müssen Sie einen eigenen Konvertierungsfilter installieren und dessen Pfad in der Datei /etc/printcap angeben. Ein Konvertierungsfilter verhält sich im Prinzip wie ein Textfilter bei einer einfachen Druckerkonfiguration (lesen Sie dazu auch den Abschnitt Den Textfilter installieren), allerdings konvertiert er die Datei in ein Format, das Ihr Drucker versteht, anstatt normalen Text zu drucken.
Sie sollten nur Filter installieren, die Sie auch benötigen. Wenn Sie sehr viele DVI-Dateien drucken, sollten Sie auch einen DVI-Konvertierungsfilter installieren. Müssen Sie viele troff-Daten drucken, ist ein troff-Filter hilfreich.
Die folgende Tabelle listet die von LPD unterstützten Filter sowie die Einträge in /etc/printcap auf, mit denen Sie diese Fähigkeiten aktivieren. Zusätzlich wird angegeben, wie Sie lpr jeweils aufrufen müssen:
Dateityp | /etc/printcap-Fähigkeit | lpr-Option |
---|---|---|
cifplot | cf | -c |
DVI | df | -d |
plot | gf | -g |
ditroff | nf | -n |
FORTRAN-Text | rf | -f |
troff | tf | -f |
Rasterdaten | vf | -v |
Normaler Text | if | keine, -p , or -l |
Wollen Sie also lpr -d
verwenden,
muss die df-Fähigkeit in /etc/printcap aktiviert sein.
Obwohl manche Leute etwas anderes behaupten, sind Formate wie FORTRAN-Text und -Plot
inzwischen nahezu obsolet. Wenn Sie diese Formate dennoch benötigen, installieren
Sie einfach einen angepassten Filter. Wollen Sie beispielsweise zwar Printerleaf-Dateien
(also Dateien des Desktop Publishing-Programms von Interleaf), aber keine Plotdateien
drucken, so können Sie einen Printerleaf-Konvertierungsfilter installieren, der es
durch die Aktivierung der gf-Fähigkeit erlaubt, diese
Dateien direkt zu drucken. Nun müssen Sie Ihren Mitarbeitern nur noch mitteilen,
dass lpr -g
nun für
“drucke Printerleaf-Dateien” steht.
Da Konvertierungsfilter nicht zum Basissystem von FreeBSD gehören, sollten diese unter /usr/local installiert werden. Häufig wird das Verzeichnis /usr/local/libexec verwendet, da es sich bei Konvertierungsfiltern um spezielle Programme handelt, die nur von LPD, aber nicht von einem normalen Benutzer gestartet werden.
Um einen Konvertierungsfilter zu aktivieren, müssen Sie dessen Pfad zusätzlich zur benötigten Fähigkeit in der Datei /etc/printcap eintragen.
In unserem Beispiel wollen wir einen DVI-Konvertierungsfilter für den Drucker bamboo installieren. Unsere bereits bekannte /etc/printcap wurde allerdings um die df-Fähigkeit für den Drucker bamboo erweitert:
# # /etc/printcap des Rechners rose - neuer df-Filter für bamboo # rattan|line|diablo|lp|Diablo 630 Line Printer:\ :sh:sd=/var/spool/lpd/rattan:\ :lp=/dev/lpt0:\ :if=/usr/local/libexec/if-simple: bamboo|ps|PS|S|panasonic|Panasonic KX-P4455 PostScript v51.4:\ :sh:sd=/var/spool/lpd/bamboo:\ :lp=/dev/ttyd5:ms#-parenb cs8 clocal crtscts:rw:\ :if=/usr/local/libexec/psif:\ :df=/usr/local/libexec/psdf:
Beim DVI-Filter handelt es sich um ein Shell-Skript namens /usr/local/libexec/psdf:
#!/bin/sh # # psdf - DVI-nach-PostScript Druckerfilter # Installiert unter: /usr/local/libexec/psdf # # Wird von lpd aktiviert, wenn der Nutzer lpr -d eingibt. # exec /usr/local/bin/dvips -f | /usr/local/libexec/lprps "$@"
Dieses Skript startet dvips im Filtermodus (durch das
Argument -f
wird der Druckauftrag über die
Standardeingabe entgegengenommen). Danach wird der PostScript-Druckerfilter lprps (lesen
Sie dazu auch den Abschnitt Drucken von reinen
Textdateien auf einem PostScript-Drucker) mit den von
LPD übergebenen Argumenten gestartet. Das lprps-Werkzeug wiederum nutzt diese Argumente, um die gedruckten
Seiten zu verrechnen.
Da es keine verbindliche Prozedur zur Installation eines Druckerfilters gibt, folgen nun weitere Beispiele in diesem Abschnitt. Verwenden Sie diese, um Ihre eigenen Filter zu erstellen. Falls ein Filter Ihren Anforderungen bereits entspricht, können Sie ihn auch direkt verwenden.
Das erste Beispiel beschreibt einen Konvertierungsfilter für GIF-Dateien für den Drucker LaserJet III-Si von Hewlett Packard:
#!/bin/sh # # hpvf - Konvertiert GIF-Dateien nach HP/PCL, danach wird gedruckt. # Installiert unter: /usr/local/libexec/hpvf PATH=/usr/X11R6/bin:$PATH; export PATH giftopnm | ppmtopgm | pgmtopbm | pbmtolj -resolution 300 \ && exit 0 \ || exit 2
Dieser Filter konvertiert eine GIF-Datei in eine portable Anymap, diese in ein portables Graustufenbild, dieses wiederum in eine portable Bitmap, die schließlich in ein LaserJet/PCL-kompatibles Format umgewandelt wird.
/etc/printcap muss für einen Drucker, der diesen Filter nutzen will, folgenden Eintrag enthalten:
# # /etc/printcap des Rechners orchid # teak|hp|laserjet|Hewlett Packard LaserJet 3Si:\ :lp=/dev/lpt0:sh:sd=/var/spool/lpd/teak:mx#0:\ :if=/usr/local/libexec/hpif:\ :vf=/usr/local/libexec/hpvf:
Das folgende Skript ist ein Konvertierungsfilter, der das Drucken von troff-Daten des groff-Textsatzsystems auf dem PostScript-Drucker bamboo ermöglicht:
#!/bin/sh # # pstf - Konvertiert groff's troff-Daten nach PS, dann wird gedruckt. # Installiert unter: /usr/local/libexec/pstf # exec grops | /usr/local/libexec/lprps "$@"
Dieses Skript nutzt wiederum lprps, um mit dem Drucker zu kommunizieren. Wäre der Drucker an einem parallelen Port angeschlossen, würde das Skript so aussehen:
#!/bin/sh # # pstf - Konvertiert groff's troff-Daten nach PS, danach wird gedruckt. # Installiert unter: /usr/local/libexec/pstf # exec grops
Das ist alles. Um den Filter verwenden zu können, müssen Sie ihn allerdings noch in /etc/printcap aktivieren:
:tf=/usr/local/libexec/pstf:
Das nächste Skript ist ein FORTRAN-Textfilter für jeden Drucker, der normalen Text direkt drucken kann und der hier für den Drucker teak installiert wird:
#!/bin/sh # # hprf - FORTRAN-Textfilter für den Drucker LaserJet 3si: # Installiert unter: /usr/local/libexec/hprf # printf "\033&k2G" && fpr && printf "\033&l0H" && exit 0 exit 2
Zusätzlich benötigen wir wiederum einen Eintrag in /etc/printcap, um diesen Filter für den Drucker teak zu aktivieren:
:rf=/usr/local/libexec/hprf:
Das letzte Beispiel ist etwas komplexer. Es soll ein DVI-Filter für den bereits erwähnten LaserJet-Drucker teak installiert werden. Der erste Teil ist einfach: Sie müssen den Pfad des DVI-Filters in /etc/printcap eintragen:
:df=/usr/local/libexec/hpdf:
Nun kommt der schwierige Teil: Sie müssen den Filter funktionsfähig machen. Dazu benötigen Sie einen DVI-nach-LaserJet/PCL-Konverter. Glücklicherweise enthält die FreeBSD Ports-Sammlung mit print/dvi2xx ein solches Programm. Nach der Installation des Pakets verfügen wir über das Programm dvilj2p, das zur Konvertierung von DVI-Daten in zu den Druckern LaserJet IIp, LaserJet III, sowie LaserJet 2000 kompatible Codes benötigt wird.
Durch den Einsatz von dvilj2p wird der Filter hpdf relativ komplex, da dvilj2p nicht von der Standardeingabe lesen kann, sondern als Eingabe einen Dateinamen erwartet. Zusätzlich muss der Dateiname auf .dvi enden, daher ist die Verwendung von /dev/fd/0 als Standardeingabe problematisch. Wir können diese Problem aber umgehen, indem wir einen temporären Dateinamen symbolisch nach /dev/fd/0 linken. Dadurch wird dvilj2p gezwungen, dennoch von der Standardeingabe zu lesen.
Das letzte Problem, das wir noch lösen müssen, ist, dass wir /tmp nicht als temporären Link verwenden können. Symbolische Links gehören dem User sowie der Gruppe bin. Der Filter läuft aber als User daemon. Außerdem ist /tmp durch ein Sticky-Bit gesichert. Daher kann der Filter den Link zwar erzeugen, ein Aufräumen ist aber nicht mehr möglich, weil sich die Eigentümer des Filters und des temporären Verzeichnisses unterscheiden.
Daher legt der Filter den symbolischen Link im Arbeitsverzeichnis an, das gleichzeitig als Spooling-Verzeichnis dient (festgelegt durch die Aktivierung der sd-Fähigkeit in /etc/printcap). Das Arbeitsverzeichnis ist ein idealer Ort für den Filter, insbesondere da dieses (manchmal) sogar über mehr freien Speicherplatz als /tmp verfügt.
Mit diesen Informationen sind wir nun in der Lage, den Filter zu entwickeln:
#!/bin/sh # # hpdf - DVI-Daten auf einen HP/PCL-Drucker drucken # Installiert unter: /usr/local/libexec/hpdf PATH=/usr/local/bin:$PATH; export PATH # # Eine Funktion zum Aufräumen unserer temporären Dateien. # Diese finden sich im Arbeitsverzeichnis, das wir auch als # Spooling-Verzeichnis für unseren Drucker verwenden werden. # cleanup() { rm -f hpdf$$.dvi } # # Eine Funktion, um fatale Fehler zu behandeln. Dazu die Meldung # ausgeben, danach ein exit 2. Dadurch weiß LPD, dass es # den Auftrag nicht noch einmal drucken soll. # fatal() { echo "$@" 1>&2 cleanup exit 2 } # # Wenn ein Anwender den Auftrag entfernt, sendet LPD ein SIGINT, daher # wollen wir SIGINT und einige andere Signale abfangen (trappen), um # nach der Konvertierung aufräumen zu können. # trap cleanup 1 2 15 # # Bevor wir anfangen, räumen wir noch auf. Sicher ist sicher. # cleanup # # Die DVI-Eingabedatei auf die Standardeingabe linken (die zu druckende # Datei). # ln -s /dev/fd/0 hpdf$$.dvi || fatal "Konnte Symlink nicht anlegen!" # # Umwandeln: LF = CR+LF # printf "\033&k2G" || fatal "Konnte Drucker nicht initialisieren!" # # Konvertieren und drucken. Da der Rückgabewert von dvilj2p # unzuverlässig ist, ignorieren wir ihn einfach. # dvilj2p -M1 -q -e- dfhp$$.dvi # # Aufräumen und beenden. # cleanup exit 0
Alle in diesem Abschnitt besprochenen Konvertierungsfilter sind zwar sehr hilfreich, allerdings müssen Sie nach wie vor bei jedem Aufruf von lpr(1) angeben, welchen Filter sie verwenden wollen, was mit der Zeit sicher nervend wird. Schlimmer ist allerdings, dass die Auswahl eines unpassenden Filters dazu führen kann, dass Sie Hunderte Seiten Papier ausdrucken.
Statt also Konvertierungsfilter zu installieren, könnten Sie den Textfilter (der ohnehin der Standardfilter ist) verwenden, um den zu druckenden Dateityp zu erkennen und anschließend den korrekten Konvertierungsfilter auszuwählen. Um den Dateityp zu bestimmen, können Sie beispielsweise file verwenden. Leider ist es bei einigen Dateitypen problematisch, diese zu unterscheiden. Daher könnten Sie für diese Dateitypen dennoch einen Konvertierungsfilter installieren.
Die FreeBSD Ports-Sammlung enthält mit apsfilter (print/apsfilter) einen Textfilter, der diese automatische Konvertierung durchführen kann. Er ist in der Lage, normalen Text, PostScript, DVI und beinahe jede Art von Datei zu erkennen, diese zu konvertieren und auf Ihren Drucker auszugeben.
LPD unterstützt noch eine weitere Filterart, die sogenannten Ausgabefilter. Diese sind - analog zu einem Textfilter - für den Druck von normalem Text ausgelegt, allerdings verfügen sie im Vergleich zu diesen nur über sehr eingeschränkte Fähigkeiten. Wenn Sie einen Ausgabefilter (aber keinen Textfilter) verwenden, dann
startet LPD nur einen Ausgabefilter für den kompletten Druckauftrag, statt für jede Datei des Auftrags einen eigenen Filter zu starten.
kümmert sich LPD nicht darum, den Beginn oder das Ende einer Datei innerhalb des Druckauftrages zu finden.
übergibt LPD weder den Benutzer- noch den Rechnernamen desjenigen, der den Druckauftrag erteilt hat, an den Ausgabefilter, was eine Verrechnung von Druckaufträgen unmöglich macht. Ausgabefilter unterstützen insgesamt nur zwei Argumente:
filter-name -w width -l length
width basiert auf der pw-Fähigkeit, length hingegen auf der pl-Fähigkeit des gewählten Druckers.
Lassen Sie sich von dieser angeblichen Einfachheit eines Ausgabefilters nicht täuschen. Ausgabefilter sind beispielsweise nicht dazu in der Lage, jede Datei eines Druckauftrages auf einer neuen Seite zu drucken. Dazu benötigen Sie einen Textfilter (die im Abschnitt Den Textfilter installieren beschrieben werden). Außerdem sind Ausgabefilter in Wirklichkeit komplexer, da sie den gesendeten Bytestrom nicht nur auf Sonderzeichen hin untersuchen müssen, sondern auch die Übertragung von Signalen für LPD übernehmen müssen.
Sie benötigen Ausgabefilter aber dann, wenn Sie Deckblätter drucken wollen, da dazu Escape-Sequenzen und Initialisierungsstrings erforderlich sind. (Es ist allerdings nicht möglich, den Druck dieser Deckblätter zu verrechnen, da LPD keine Benutzer- oder Rechnerinformationen an den Ausgabefilter übergibt.)
LPD kann für den gleichen Drucker sowohl Ausgabefilter als auch Textfilter verwenden. In solchen Fällen verwendet LPD den Aus