Ich bin vor einigen Jahren schon auf die Möglichkeit gestoßen, mit der Installation von CUPS-PDF einen virtuellen PDF-Drucker anzulegen.
Interessanterweise ist CUPS, das UNIX-Drucksystem, flexibler, als ich erst dachte: Auch ohne Installation weiterer Software (von GhostScript mal abgesehen) lassen sich Druckaufträge in PDF wandeln oder sonstige Skripte anstoßen.
Das Meiste der hier aufgelisteten Informationen konnte ich aus diesem Artikel entnehmen.
Für was braucht man sowas?
Einerseits, um lokal an dem Computer, an dem die PDF-Erstellungs-Funktion eingerichtet ist, über den Druckdialog PDFs erstellen zu können, die darauf in einem Ausgabeordner landen oder per E-Mail zugesendet werden oder auch, um einen Druckserver anzulegen, auf den man von anderen Computern aus "druckt"; welcher die erstellten PDFs dann an gewünschter Stelle ablegt oder auch per E-Mail versendet.In meinem Fall gibt es auch automatisierte Prozesse anderer Server, die in bestimmten Fällen Ausdrucke erstellen, welche der CUPS-Server in ein PDF umleitet, je nach Sender und Inhalt benennt und archiviert oder an andere Personen weiterleitet.
Die Anwendungsgebiete sind mannigfaltig.
Einrichtung
Voraussetzung
UNIX-Server/Computer mit CUPS, installiertes GhostScript (um aus den eingehenden PostScripts PDFs erstellen zu können).
Die Puzzle-Teile
/etc/samba/smb.conf Samba-Konfiguration (zu ändern, um via Samba Druckaufträge von
Windows-Rechnern annehmen zu können)
/var/spool/samba Samba-Spool-Verzeichnis, in dem die Druckaufträge eingehen
/var/spool/pdf * Unser-PDF-Ausgabeverzeichnis
/usr/lib/cups/backend/pdf *# Bash-Skript. Dies ist unser virtueller Drucker
/usr/lib/cups/pdf/ps2pdf.cups *# Bash-Skript, welches letztendlich aus der eingehenden
PostScript-Datei mit Hilfe von GhostScript ein PDF erstellt
* = Datei/Verzeichnis muss erstellt werden
# = Auf dem Mac: /usr/libexec/cups/...
/var/spool/pdf kann auch an besser erreichbarer Stelle, wie z.B. ~/pdfdrucker, liegen (wobei der Pfad in der Konfiguration dann voll ausgeschrieben werden sollte, z.B. /home/apfelz/pdfdrucker).
Es können später beliebig viele virtuelle PDF-Drucker mit unterschiedlichen Ausgabepfaden erstellt werden.
Sollen später mehrere virtuelle Drucker angelegt werden, die verschiedenen Verarbeitungsregeln folgen (z.B. einer erstellt nur ein PDF und legt es ab, ein anderer versendet es per E-Mail, ein weiterer archiviert das PDF an Hand des Inhalts,...), muss je unterschiedlicher Verarbeitung eine weitere Backend-Datei á la /usr/lib/cups/backend/pdf angelegt werden.
Am besten sollte man diese Backend-Dateien gleich von Anfang an korrekt benennen, um ihre Funktion erkennen zu können (z.B. /usr/lib/cups/backend/pdffile, /usr/lib/cups/backend/pdfmail, /usr/lib/cups/backend/pdfarchiv,...).
Bei mehreren Backends achtet bitte auf mein Kommentar im Backend-Skript so in Zeile 10! Je Backend muss hier eine Anpassung erfolgen!
Grundeinrichtung CUPS-System
Sollte CUPS noch jungfräulich sein, empfiehlt es sich, einen Blick in die Konfiguration /etc/cups/cupsd.conf zu werfen. Standardmäßig lässt CUPS es nicht zu, dass es durch Druckaufträge anderer Computer belästigt wird. Zuvor am besten ein Backup erstellen.sudo cp /etc/cups/cupsd.conf /etc/cups/cupsd.conf.bak
Hier die Ausschnitte aus cups.conf, die ich geändert oder hinzugefügt habe. Alles in der Annahme "Alle Computer im internen Netzwerk sind friedlich".
Browsing On
BrowseLocalProtocols dnssd
DefaultAuthType Basic
<Location />
Order allow,deny
Allow From All
</Location>
<Location /admin>
Order allow,deny
Allow From All
</Location>
<Location /admin/conf>
AuthType Default
Require user @SYSTEM
Order allow,deny
</Location>
Grundeinrichtung Samba
Auch hier am besten wieder erst ein Backup erstellen:sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak
Samba stellt die CUPS-Drucker den Windows-PCs im lokalen Netzwerk zur Verfügung, wenn folgende Zeilen in der
[global]-Sektion vorhanden sind:
security = user
guest account = nobody
load printers = yes
invalid users = root
printcap name = cups
printing = cups
Außerdem sollte es noch eine Sektion
[printers]geben:
comment = All Printers
browseable = no
path = /var/spool/samba
printable = yes
public = yes
guest ok = yes
create mask = 0777
create mode = 0777
use client driver = yes
Sollte das Spool-Verzeichnis /var/spool/samba noch nicht existieren, dann muss es natürlich noch angelegt werden. Ob es existiert und ob die Berechtigungen korrekt sind, ist schnell geprüft:
drwxrwxrwt 2 root root 4096 2016-05-11 19:55 samba/
Falls es nicht existiert:
chown -R root:root /var/spool/samba
chmod 1777 /var/spool/samba
Neues CUPS-Backend
CUPS verwendet sogenannte backends, um auf Drucker zuzugreifen. Beispiele für solche backends sind ipp, lpd und socket. Jedes Backend hat eine bestimmte URI, so dass die Backends bei der Druckereinrichtung unterschieden werden können.Ein Beispiel für die URI eines IPP-Druckers: ipp://172.17.60.122/print/hp1200
Unser neuer PDF-Drucker wird auf Grund des Dateinamens des Skriptes /usr/lib/cups/backend/pdf (es handelt sich hier trotz fehlender .sh-Dateiendung um ein Shell-Skript) die URI pdf:// erhalten.
Das Ausgabeverzeichnis des PDFs ist in diesem Skript nicht enthalten. Dieses wird später bei der Einrichtung des eigentlichen virtuellen Druckers angegeben und jedes Mal beim Drucken an das Skript weitergegeben.
Folgendes Backend-Skript kann also für mehrere virtuelle Drucker verwendet werden, die die PDFs jeweils an unterschiedlichen Stellen ablegen.
PDFBIN=/usr/lib/cups/pdf/ps2pdf.cups
PRINTTIME=`date +%Y-%m-%d_%H.%M.%S`
# Kein Argument übergeben
if [ $# -eq 0 ]; then
if [ ! -x "$PDFBIN" ]; then
exit 0
fi
# WICHTIG: Hier muss nochmals der verwendete Backend-Name
# (in diesem Fall "pdf") stehen. Werden weitere Backends angelegt, so
# ist die folgende Zeile entsprechend anzupassen!
# z.B. echo "direct pdfmail \"Unknown\" \"PDF Creator\""
echo "direct pdf \"Unknown\" \"PDF Creator\""
exit 0
fi
# case of wrong number of arguments
if [ $# -ne 5 -a $# -ne 6 ]; then
echo "Usage: pdf job-id user title copies options [file]"
exit 1
fi
# PDF-Verzeichnis aus der URI auslesen und Zugriffsrechte prüfen
# WICHTIG: Auch hier wäre der Backend-Name #pdf anzupassen
PDFDIR=${DEVICE_URI#pdf:}
if [ ! -d "$PDFDIR" -o ! -w "$PDFDIR" ]; then
echo "ERROR: directory $PDFDIR not writable"
exit 1
fi
# generate output filename
OUTPUTFILENAME=
if [ "$3" = "" ]; then
OUTPUTFILENAME="$PDFDIR/unbenannt.pdf"
else
if [ "$2" != "" ]; then
OUTPUTFILENAME="$PDFDIR/$2-$PRINTTIME.pdf"
else
OUTPUTFILENAME="$PDFDIR/$PRINTTIME.pdf"
fi
fi
# run ghostscript
if [ $# -eq 6 ]; then
$PDFBIN $6 $OUTPUTFILENAME >& /dev/null
else
$PDFBIN - $OUTPUTFILENAME >& /dev/null
fi
# Datei gehört nach Erstellung zu Benutzer und Gruppe ++lp:lp++
# Ändere ich hier auf den lokalen Benutzer (z.B. apfelz) und gebe allen
# Benutzern das Recht zum Öffnen, löschen & Co.
chown apfelz $OUTPUTFILENAME
chmod 777 $OUTPUTFILENAME
exit 0
Der Backend-Name (in oberem Fall pdf muss im Skript an zwei Stellen unter derselben Bezeichnung vorkommen. Dies wäre zu beachten, sollte man sein Backend umbenennen und/oder mehrere Backends erstellen.
Nehmen wir an, wir erstellen noch ein zweites Backend /usr/lib/cups/backend/pdfmail:
- Zeile 15: echo "direct pdfmail \"Unknown\" \"PDF Creator\""
- Zeile 27: PDFDIR=${DEVICE_URI#pdfmail:}
Existieren in /usr/lib/cups/backend/ mehrere Backend-Skripte, die an diesen Stellen denselben Namen haben, werden diese nicht funktionieren.
Dieses Skript muss exklusiv für den Root-User ausführbar sein. Ist es für sämtliche Benutzer/Gruppen ausführbar, wird es später mit einem unprivilegierten Benutzer wie etwa lp ausgeführt und nicht funktionieren:
sudo chmod 755 /usr/lib/cups/backend/pdf
Das backend müsste nun aufgelistet werden, wenn man den Befehl
ausführt.
Skript zur PDF-Erstellung
Die in diesem Backend verwendetePDFBIN=/usr/lib/cups/pdf/ps2pdf.cupssollte dieselben Zugriffsrechte wie eben erwähnt besitzen und ist der eigentliche PDF-Ersteller. Die Backend-Datei fängt nur mögliche Fehler ab und kümmert sich um die Dateinamensvergebung.
OPTIONS=""
while true
do
case "$1" in
-*) OPTIONS="$OPTIONS $1" ;;
*) break ;;
esac
shift
done
if [ $# -lt 1 -o $# -gt 2 ]; then
echo "Usage: `basename $0` [options...] input.ps [output.pdf]" 1>&2
exit 1
fi
infile=$1;
if [ $# -eq 1 ]
then
outfile=$1
else
outfile=$2
fi
# Doing an initial 'save' helps keep fonts from being flushed between pages.
exec gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite \
-sOutputFile=$outfile $OPTIONS -c save pop -f $infile
Info: Die PDF-Erstellung hatte bei mir anfangs überhaupt nicht funktioniert. Irgendwo tief im Log /var/log/cups/error_log war etwas von wegen "bad fd number" zu finden. Dies hatte die Ursache, dass ich im Backend-Skript den Shebang #!/bin/sh statt #!/bin/bash verwendet hatte.
Auch ein Leerzeichen vor dem Shebang kann Probleme verursachen!
PPD
CUPS verwendet PPDs, um den eingehenden Druckjob in ein PostScript zu wandeln. Für unseren Zweck können wir die Standard-Adobe-Distiller-PPD verwenden, die Adobe hier zur Verfügung stellt. Die PPD sollte als gzip (nicht als ZIP wie von Adobe zur Verfügung gestellt) in /usr/share/cups/model/ abgelegt werden (inklusive .ppd.gz-Dateierweiterung). Beim Anlegen des Druckers greifen wir später auf sie zurück.Der Einfachheit halber hier gleich als gzip zum Download:
http://www.apfel-z.net/dl/diverses/pdfcolor.ppd.gz
Besitzer sollte auch hier root sein:
sudo chmod 644 /usr/share/cups/model/pdfcolor.ppd.gz
Neustart
CUPS und Samba neustarten, damit alle Änderungen in den Konfigurationen wirksam werden (Befehle variieren je nach Unix-System):sudo service cups restart
Drucker anlegen und Drucken lokal testen
Den Ausgabeordner, in welchem die PDFs letztendlich landen sollen, haben wir noch nicht angelegt. Ich werde ihn im Verzeichnis /var/spool anlegen, allerdings ist auch jeder andere Ort möglich.sudo chmod 777 /var/spool/pdf
Den virtuellen Drucker kann man letztendlich per CUPS-Webinterface http://*computer-ip*:631 oder per lpadmin auf der Kommandozeile anlegen:
lpadmin -p pdfprinter -D "PDF-Drucker" -v pdf:/var/spool/pdf/ -E -P /usr/share/cups/model/pdfcolor.ppd.gz
Durch die Option -E sollte der Drucker sofort aktiviert werden.
Zum Testen können wir einen Text an den Drucker senden und sollten in /var/spool/pdf/ ein PDF erhalten.
Den via lpadmin angelegten Drucker pdfprinter sollte man in /etc/cups/printers.conf wieder finden.
Außerdem ist dieser Drucker unter der URL ipp://*computer-ip*/printers/pdfprinter auch auf anderen Computern im lokalen Netzwerk nutzbar.
Druckerinfo
Eine Liste aller angelegten URIs, Druckern samt Status und Dokumenten in den Warteschlangen bekommt man mit dem Befehllpstat -t
Eine Liste aller Backends und Netzwerkdruckern bekommt man mit
lpinfo -v
AppArmor und Debugging
Unter Umständen kann das Sicherheits-Framework AppArmor dazwischenfunken (war bei mir nicht der Fall).Nur um dies mal im Hinterkopf zu behalten.
Sollten keine PDFs erstellt werden, kann ein Blick in
/var/log/cups/error_loghelfen. Unter Umständen kann es auch sinnvoll sein, den LogLevel in
/etc/cups/cupsd.confvon warn auf debug zu erhöhen, um mehr Informationen im Log zu erhalten (cups danach neustarten!).
PDF per E-Mail versenden
Auf der Seite http://alien.slackbook.org/dokuwiki/doku.php?id=slackware:cups gibt es einen interessanten Ansatz, den Druckauftrag direkt als PDF per E-Mail an die Person, die druckt, zu senden.War für meinen Fall nicht relevant, da ich sowieso nicht vom Benutzernamen auf die E-Mail-Adresse schließen kann.
Von anderen Computern im Netzwerk aus nutzen: Mac
Wir hatten in /etc/cups/cupsd.conf generellen Zugriff für alle Rechner aus dem Lokalen Netzwerk gewährt, so dass es kein Problem ist, den virtuellen Drucker auch auf anderen Rechnern als Drucker einzurichten.Die Einrichtung ist ein bisschen tricky:
Systemeinstellungen > Drucken und Faxen > Das unscheinbare + unter der Druckerliste anklicken.
IP-basierter Drucker hinzufügen, IPP-Protokoll und IP-Adresse des Servers eingeben, den wir zuvor eingerichtet hatten.Der Warteliste-Name ist aus printers/ und dem Druckernamen, wie wir ihn auf dem Server mit lpadmin angelegt hatten, zusammengesetzt. In diesem Beispiel also printers/pdfprinter.
Name und optional Standort können wie gewünscht vergeben werden, bei "Drucken mit" habe ich ebenfalls eine Adobe-PDF-PPD gewählt, die auf meinem Mac installiert war.
Von anderen Computern im Netzwerk aus nutzen: Windows
Hier die besonders umständliche Variante. Wir haben drei Windows 2008 Server. Das mag schon schlimm genug sein, aber der virtuelle Netzwerk-PDF-Drucker meines UNIX-Servers muss dort als lokaler Drucker installiert werden.Klingt seltsam, aber ist so (sonst kann die Software, die darauf läuft und die Druckjobs absendet nicht auf den Drucker zugreifen).
Interessanterweise kann man unter Windows einen Netzwekdrucker als Lokalen Drucker (statt Netzwerkdrucker) anlegen. Pervers, oder?
Ich weiche hierbei sogar noch von meiner Verfahrensweise aus diesem Artikel ab, wo ich das Problem schonmal hatte. Ich weiß nicht, ob es nun an diesem speziellen PDF-Drucker liegt oder daran, dass sich auf dem Server inzwischen die Windows-Version geändert hat.
lpadminangelegt) als Anschlussnamen verwenden
Auf jeden Fall immer einen Treiber eines Farb-PostScript-Druckers verwenden.
![]() ![]() ![]() ![]() |
|
Erstellt am: 11.05.2016 | .Kommentieren |