Brücken schreiben
The Answer Girl
Automagie
Alles, was das Herz in diesem Fall begehrt, ist ein Filter, der aus am besten sämtlichen möglichen Dateiformaten dasjenige erzeugt, dass der Drucker bevorzugt. Erinnert sich jemand an die Druckereinrichtung bei der Linux-Installation? Falls Ihnen jetzt apsfilter, magicfilter oder rhs-printfilters einfällt, liegen Sie genau richtig.
Der Magicfilter im Netz
- Die Quelltexte zum Selberbauen: ftp://metalab.unc.edu/pub/Linux/system/printing/magicfilter-1.2.tar.gz
- Die aktuellsten Debian-Pakete: http://www.debian.org/distrib/packages/ -->Search Packages-->magicfilter
- RPM-Pakete (leider nur libc5-basiert): http://rpmfind.net/linux/RPM/magicfilter.html
Diese Werkzeuge suchen für Druckjobs in der Unix-Druckerwarteschlange automagisch heraus, welche Konvertierungsmethode zum druckerinternen Format für die verschiedenen Eingangsformate sinnvoll ist: PostScript-Dateien schickt man bei nicht-PostScript-fähigen Druckern sinnvollerweise durch das Ghostscript-Konvertierungstool gs, während ein jpg-Bildchen zuvor erst noch mit djpeg ins pnm-Format (pnm steht für "Portable Anymap") gewandelt wird, aus dem pnmtops PostScript macht.
Bleibt die Frage, wie wir diesen magischen Filter dazu bekommen, unser auszudruckendes File zu behandeln, das wir ja nun gerade nicht auf einen intern konfigurierten Drucker schicken? Wenn SuSE auf seine Version des apsfilters schwört und Red Hat seit einigen Versionen mit den rhs-printfilters ebenfalls ein eigenes Süppchen braut, wird es schwierig, alle Fliegen mit einer Klappe zu schlagen.
Zumal man beim Durchsehen der aus dem Druckfilterpaket installierten Dateien – eine Liste bekommt man per rpm -ql aps bei SuSE ( rpm -ql yaps für SuSE 6.4) bzw. rpm -ql rhs-printfilters bei Red Hat & Co. – recht schnell merkt, dass deren Struktur reichlich komplex ist. Was wir gern hätten, ist eine einzige ausführbare Datei, die wir ohne weitere Mätzchen als Filtervor den smbclient schalten können.
ProgrammA | FilterA
ProgrammA produziert eine Ausgabe, die, durch die Pipe | gejagt, im FilterA verarbeitet und ausgegeben wird. Mit
FilterA | FilterB
könnte FilterB die Ausgabe von FilterA weiter verarbeiten.
Magicfilter – so merken zumindest die, die Debian oder eine Derivatdistribution installiert haben – eignet sich hingegen hervorragend für unsere Zwecke. Doch auch Benutzern anderer Distributionen steht dieser Weg (notfalls durch Selbstkompilieren) offen.
So kompiliert man Magie
Die Installation eines im Quellcode vorliegenden Magicfilters folgt dem oft wiederholten Schema
- auspacken:
tar -xzvf magicfilter-1.2.tar.gz
- ins entstandene Verzeichnis wechseln:
cd magicfilter-1.2
- ans eigene System anpassen (lassen):
./configure
- kompilieren:
make
- … und als root…
su -(root-Passwort eingeben)
- … in den Verzeichnisast /usr/local installieren:
make install
Was jetzt – und hier verlassen wir die Standardprozedur – noch fehlt, sind die Filter:
make install_filters
… installiert die Filter – genauso wie schon das eigentliche magicfilter-Programm selbst – nach /usr/local/bin. Wer die magischen Filter lieber nicht systemweit installieren will, kann alles genau so machen – bis auf den configure-Aufruf. Mit
./configure --prefix=$HOME
legen Sie stattdessen fest, dass Sie keinerlei root-Rechte brauchen (also später auch kein su), weil Filter und magicfilter selbst ins Unterverzeichnis bin Ihres Homeverzeichnisses installiert werden. Dies legen Sie vor dem make install mit
mkdir $HOME/bin
an, falls es noch nicht existiert.
Außerdem empfiehlt es sich, Ihren Suchpfad anzupassen:
export PATH=$PATH:$HOME/bin
Falls Sie bei make install die Fehlermeldung
/usr/bin/install: cannot create regular file `/home/trish/man/man8/magicfilter.8': No such file or directory make: *** [install] Error 1
stört (oder Sie grundsätzlich nicht auf die Manpage verzichten wollen), legen Sie das fehlende Verzeichnis vor dem Installieren mit
mkdir -p $HOME/man/man8
an (das -p wie "parent" – "Elternverzeichnis" – sorgt dafür, dass Sie $HOME/man und $HOME/man/man8 auf einen Schlag erzeugen) und ergänzen den Manpage-Suchpfad um $HOME/man:
export MANPATH=$MANPATH:$HOME/man
Sinnvoll ist es, die beiden Umgebungsvariablen PATH und MANPATH im Konfigurationsfile Ihrer Shell (z.B. $HOME/.bashrc) dauerhaft zu verankern.
Selbstkompilierer suchen nun in /usr/local/bin oder – siehe Kasten "So kompiliert man Magie" – $HOME/bin nach einer Filterdatei, die in etwa Ihrem Druckernamen entspricht. Wo ein Paket-Managerden "Kram" hingepackt hat, verrät er im allgemeinen selbst.
rpm -ql magicfilter | less
lautet die Frage bei SuSE, Red Hat und Co.: -q für "query – abfragen" und -l für "auflisten (sämtlicher vom Paket installierter Dateien)". Das Ganze wird mit less in eine seitenweise blätter- (Leertaste – vorwärts, b rückwärts ("backward")) und durchsuchbare (/suchbegriff) Form gebracht. Auf "debianische" Weise heißt es hingegen
dpkg -S magicfilter | less
mit -S wie "Search" resp. "Suche nach Dateien aus dem Paket".
Zur Not kann man auch noch locate magicfilterless bemühen… So kommt man für einen HP LaserJet 4 Plus unter Debian beispielsweise auf /etc/magicfilter/ljet4l-filter. Jede der filter-Dateien enthält zu Beginn eine kurze Beschreibung, für welche Drucker(familie) sie geeignet ist, hier beispielweise für die "300-DPI-LaserJet-4-Serie ohne PostScript-Unterstützung".
Die gefundene Datei erweist sich als ganz normales Shell-Skript, mit dem Unterschied, dass der Magicfilter die aufgerufene "Shell" ist:
#! /usr/sbin/magicfilter
Wer die Filter in $HOME/bin (siehe Kasten "So kompiliert man Magie") installiert hat, staunt jetzt ein wenig: Wieso steht da
#! /usr/local/bin/magicfilter
…, wo doch eigentlich
#! /home/Ihr_Benutzername /bin/magicfilter
richtig wäre? Kleiner Bug – große Wirkung, doch mit einem beherzten Griff zum Texteditor ist der Schlamassel leicht behoben.
Damit könnten wir endlich eine Testdatei hernehmen (hier die PostScript-Datei test.ps), diese durch den magischen Filter schieben (Der Name "Filter" weist schon zaunspfahlmäßig darauf hin, dass eine Pipehier wohl das Gelbe vom Ei ist.) und das Ergebnis, durch den "Trichter" > geschickt, in einer Datei namens test.prn auffangen:
cat test.ps | /etc /magicfilter/ljet4l -filter > test.prn
Wenn wir jetzt smbclient aufrufen und auf dessen Prompt mit
print test.prn
antworten, sollte unser SMB-Drucker eigentlich mit einem schön bedruckten Blatt Papier antworten.
Wer wird denn alles von Hand machen?
Ganz schön umständlich, die Prozedur… Da muss es doch einen Weg geben, um das Ganze mit weniger Arbeit für die Anwenderin zu gestalten: Warum "pipen" wir die Magicfilter-Ausgabe nicht einfach durch den smbclient? Das am Prompt einzugebende print ist da wohl im Weg – oder auch nicht.
Eine Schmökerstunde hilft da weiter: Hinter der Beschreibung der -c-Option, der eine Kommandoliste folgen soll, verheißt die smbclient-man-Page Gutes. "Dies ist besonders nützlich in Skripten und wenn man die Standardeingabe auf dem Server ausdrucken will, z. B. -c 'print '".
Damit generieren wir einen höllischen Rattenschwanz…
cat test.ps | /etc /magicfilter/ljet4l -filter | smbclient \\\\server \\drucker -W arbeitsgruppe -U SMB-benutzername -c 'print -'
…, den sich natürlich kein Mensch merken kann. Schreiben wir ihn daher besser in ein klitzekleines Shell-Skript (Listing 1). Zum Glück gibt es in Shells wie der Bash ein paar spezielle Variablen, in denen ein Skript Parameter "durchgestellt" bekommt, mit denen es auf der Kommandozeile aufgerufen wurde.
* ist so einer: Diese Variable enthält die Argumente. Wie bei jeder anderen Shell-Variablen auch kann man ihren Inhalt erfragen, indem man ein $ davor setzt: $* liefert alle Parameter in einer Zeichenkette, getrennt von einem (in der Umgebungsvariablen IFS festgelegten) Trennzeichen, in der Regel einem Whitespace-Zeichen.
Listing 1
Ausdrucken auf dem SMB-Drucker – das Skript
#!/bin/sh
# Dieses Skript ist nicht perfekt: Wer mag,
# kann hier z. B. mit $@
statt $*
,
# einer for
-Schleife, if
und
# einem test
(resp. [ ]
)
# nachpruefen, ob die als Argumente
# angegebenen Dateien tatsaechlich
# existieren, und ggf. mit echo
# huebsche Fehlermeldungen ausgeben.
# Wie so oft fallen diesbezuegliche
# Erklaerungen dem beschraenkten
# Answer-Girl-Platz zum Opfer...
cat $* | /etc
/magicfilter/ljet4l
-filter | \
smbclient \\\\server
\\drucker
\
-W arbeitsgruppe
\
-U "SMB-benutzername%passwort
" \
-c 'translate; print -'
Das Listing enthält still und heimlich eine weitere Weisheit aus dem unerschöpflichen Reichtum der smbclient-Manpage: Wer hinter den SMB-benutzernamen ein % samt SMB-passwort schreibt, wird den expliziten Password:-Prompt sicher nicht vermissen.
Selbstverständlich haben wir für den Fall von ASCII-Texten auch gleich das translate mit eingebaut: -c nimmt gern mehrere Kommandos unter seine Fittiche, sofern sie mit Semikolon voneinander getrennt sind.
Das Skript spart zugleich noch Papier: ASCII-Dateien enthalten – anders als PostScript – keinen Befehl, der eine neue Seite anfordert. cat kettet alle in $* angeführten Argumentdateien am Stück zusammen, was dazu führt, dass aufeinander folgende ASCII-Dateien mangels Seitenumbruch auf einem gemeinsamen Blatt Papier landen. Wem das nicht gefällt, kann dem Hinweis im Skript folgen und mit einer for-Schleife und der Sondervariablen @ experimentieren.
Neben dem obligatorischen Verleihen der Ausführungsrechte für die Skript-Eigentümerin mit chmod u+x skriptname wird sie in diesem Fall allen anderen mit chmod go-r skriptname das Leserecht entziehen. Schließlich sollte man sein Passwort nicht gleich sämtlichen Rechnermitbenutzern ans Herz legen. Befinden sich auf den mit diesem Passwort erreichbaren SMB-Shares wichtige Daten (sic!), verbietet sich ein im Skript angegebenes Passwort natürlich von selbst.
Wer seinen SMB-Drucker jetzt noch gern mit dem Druckbefehl lpr wie einen gewöhnlichen lokalen Drucker an der parallelen Schnittstelle ansprechen möchte, muss sich allerdings auf das nächste "Answer-Girl" vertrösten lassen.
Glossar
POP3
Das "Post Office Protocol" ist eine verbreitete (und für Nicht-Unix-Betriebssysteme oft die einzige) Methode, um an seine E-Mail zu kommen. Wärend auf vernetzten Unix-Systemen normalerweise ein "Mail Transfer Agent" wie sendmail, smail, qmail … eingehende Mail über das "Simple Mail Transfer Protocol" SMTP selbsttätig annimmt und in die "Briefkästen" der Benutzer verteilt, muss man bei POP3 eigenhändig zum Post-Office-Server traben und sich dort die Mail aus dem Postfach holen. Dabei wird man von allen gängigen Mail-Clients (Netscape, mutt, pine, KMail, XFMail…) oder einem Programm wie fetchmail unterstützt.
VMware
Mit diesem unter http://www.vmware.com/ erhältlichen kommerziellen und kostenpflichtigen Programm kann man in sogenannten Virtuellen Maschinen weitere Betriebssysteme ausführen, beispielsweise Linux unter Windows, Windows unter Linux oder auch eine Linux-Installation unter einer anderen.
Ob man share nun trendgemäß mit "Aktie" assoziiert oder althergebracht mit "Anteil" oder "teilen" übersetzt – der Sinn wird jedenfalls deutlich: Ein Share ist eine Ressource auf/an einem Windows- oder Samba-Rechner – sei es ein Drucker, ein Verzeichnis oder ein Laufwerk –, auf die man in einer Microsoft-Netzwerk-/Samba-Umgebung auch andere zugreifen lassen will. Die Abkürzung SMB steht für "Server Message Block", ein proprietäres Protokoll der Firma Microsoft (ursprünglich von Intel und Microsoft entwickelt), das eben solch eine verteilte Nutzung von Ressourcen ermöglicht.
IP-Adresse
Damit Rechner untereinander mit dem Internet Protocol ("IP") kommunizieren können, müssen sie eine eindeutige Adresse haben. Diese besteht (in der gegenwärtig vorherrschenden Version 4 des Internet-Protokolls) aus vier durch Punkte voneinander getrennten Dezimalzahlen zwischen 0 und 255. Darin enthalten sind die Kennung für das Netz, in dem sich der Rechner befindet, und die Hostnummer, also die "Hausnummer" des Computers. Welcher Teil der numerischen IP-Adresse Netzwerk und welcher den Host bezeichnet, wird durch die Netzmaske festgelegt. Da sich Menschen Zahlen im allgemeinen schlechter als Worte merken, bekommen viele Rechner über den Domain Name Service DNS eine meist besser bekannte textuelle IP-Adresse (z. B. www.linux-user.de) zugeordnet.
Ethernet-Device
Die Schnittstelle (das "Gerät"), über die Unix-Betriebssysteme die Netzwerkkarte ansprechen, sofern sich die Datenübertragung wie in den meisten lokalen Netzen "technisch gesehen" auf einem Ethernet-Netz abspielt.
Shell
Die "Schale" um den Betriebssystem-Kern(el) ermöglicht es überhaupt erst, mit Linux befehlenderweise zu kommunizieren. Außer der Auswertung und Weiterleitung einfacher Kommandos stellen aus der Unix-Welt kommende Shells auch Programmiersprachenelemente wie Schleifen und konditionale Abfragen zur Verfügung. Wie fast immer hat man auf einem Linux-/Unix-Rechner hier die Qual der Wahl: Unterschiedliche Shells wie die Linux-Standardshell bash, die zsh oder die an die Programmiersprache C angelehnten csh oder tcsh bieten unterschiedlichen Bedienkomfort und beliebig umfangreiche Funktionalität.
PostScript
Eine Programmier-, Seitenbeschreibungs- und Druckersprache der Firma Adobe. PostScript hat sich hauptsächlich in der Unix-Welt als Zwischenformat für Ausdrucke etabliert. Leider verstehen nur vergleichsweise teure (Laser-)Drucker von Haus aus PostScript, so dass für Nicht-PostScript-fähige Drucker noch ein Filter nötig ist, der das PostScript-Standardformat in die vom Drucker verwendete Sprache (meist PCL) übersetzt. Diese Aufgabe nimmt in der Regel Ghostscript wahr.
Filter
Ein Programm, das seine Eingabe gewöhnlich von der Standardeingabe bezieht und – auf die eine oder andere Weise behandelt – auf der Standardausgabe wieder ausspuckt. Filter werden normalerweise an Pipes ("Rohrleitungen") "angeschlossen", z. B. so:
$HOME
Die Umgebungsvariable HOME enthält den Ort, an dem sich Ihr Homeverzeichnis befindet. Das $-Zeichen davor veranlasst, dass Sie ihren Inhalt heraus bekommen.
Paket-Manager
Ein Hilfsprogramm, das eine Datenbank führt, in der möglichst sämtliche installierte Software-Pakete mit ihren wechselseitigen Abhängigkeiten verzeichnet sind, so dass sie sich sauber installieren und deinstallieren lassen.
Shell-Skript
Die meisten Unix-Shells verfügen über eine eingebaute Programmiersprache, mit der man kleine oder auch größere Programme schreiben kann. Die muss man jedoch nicht erst mit einem Compiler in ausführbaren Code übersetzen, ehe man sie aufrufen kann. Stattdessen werden sie sofort von der Shell interpretiert und aus diesem Grund Skripte genannt.
#!
Fast jedes Shellskript beginnt mit einer Kommentarzeile – erkennbar am # am Zeilenanfang. Kommentare werden vom Interpreter normalerweise nicht beachtet und dienen eigentlich "nur" dem Menschen, der das Skript lesen will oder muss, als Erklärung und Gedankenstütze. Mit der #!-Zeile ist das etwas anders: An deren Hand stellt das System fest, wer denn eigentlich den ganzen folgenden Rest ausführen soll – schließlich gibt es ja verschiedene Shells, die durchaus ihre Unterschiede haben. Im Beispiel wird /usr/sbin/magicfilter bemüht. Wenn das magische #! fehlt, kommt stillschweigend /bin/sh zum Zuge, unter Linux in der Regel ein Verweis ("Link") auf die Bash.
Pipe
Die durch das Symbol | gekennzeichnete "Rohrleitung" (engl.: "Pipeline") nimmt die (Standard-)Ausgabe des links stehenden Programms entgegen und gibt sie als (Standard-)Eingabe an das rechts stehende Kommando (oft ein Filter) weiter.
cat
Ein Standard-Unix-Werkzeug, das nichts weiter tut, als die Datei(en), die es als Argument mitbekommt, auf der Standardausgabe hintereinanderweg auszugeben. cat steht kurz für "concatenate", "verketten", und weist darauf hin, dass das Ausgeben lediglich einer Datei eigentlich ziemlich langweilig ist – das Verknüpfen mehrerer Files zu einer gemeinsamen Ausgabe war wohl die eigentliche Intention.
-
Viele Kommandos, die eigentlich nicht als Filter konzipiert sind, sondern Dateinamen als Argument haben wollen, lassen sich mit Hilfe der "Pseudodatei" - ("minus") davon überzeugen, eine "durchgepipte" Standardeingabe anstelle der erforderlichen "echten" Argumentdatei zu nehmen. Weniger kompliziert ausgedrückt: - steht für die Pseudodatei STDIN alias Standardeingabe.
Whitespace
Druckbare Zeichen, bei denen das Papier aber weiß bleibt, beispielsweise Tabulatoren, Leer- oder Zeilenendezeichen.
\
Die Zeilenendesequenz wird normalerweise als Ende des Kommandos interpretiert. Maskiert man sie mit dem Fluchtzeichen \, lässt sich eine ellenlange Kommandozeile übersichtlich über mehrere Zeilen verteilen.
Infos
[1] Tom Riedl, Patricia Jung: "Rechnerlein, komm tanz mit mir", LinuxUser Sonderheft 01/2000, http://www.linux-user.de/ausgabe/2000/00/HomeNet4/samba.html



