APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed
RSS Feeds RSS Feeds











(OLDER) <- More Stuff -> (NEWER) (NEWEST)
Printer Friendly Version
->
-> CUPS (Common Unix Printing System) print to file - the hard


CUPS (Common Unix Printing System) print to file - the hard way!





Sometimes what should be simple isn't. I wanted a CUPS printer that would just print to a file. Actually, I wanted a bit more than that, but printing to a file was a reasonable start.

What I really wanted to be able to do was examine a print job and then, based on its content, put it into a particular file or perhaps send it on its way somewhere else. The reason for this is that a "printer" is often a convenient and easy abstraction that some other program can use - whether or not that program is on this machine or not. You can do (and I have done) similar things with special email addresses, but printers are often easier (see also Using System V interface scripts with CUPS printing).

So..although the ultimate place this printer would live would be on a RedHat 8.0 system, I initially attempted to configure it on my Mac OS X machine. Why? Well, because my main RedHat machine is a 7.2 box that doesn't use CUPS, and although I have an 8.0 machine, it's dual boot and at the moment it is tied up with a project I'm doing on one of its other OSes. I usually have more than one thing going on at the same time, and it would have been mildly annoying to keep rebooting that as I switched gears. Besides, Mac OS X uses CUPS, so why not?

Awful Docs

Small gripe here: aside from the problems I ran into on this, I do like CUPS. It's very flexible, I think it combines the best of SysV and BSD style printing, and I'm sure it will gain ground quickly. However: the documentation bites. Unix documentation is well known for its assumption of prior knowledge, but the CUPS docs take that to a whole new level. In my search for answers to what seemed like simple questions, I kept running into stone walls that had tantalizing hints, but very little real help. The "HowTo" reached from http://www.cups.org is mostly a long winded treatise advising you to read the manual before you dare ask a question on the newsgroup. The "Overview" isn't much help, and either is the FAQ. All very disappointing.

When I have a better handle on this myself I intend to write up something of my own.

First Attempt

One of the really nice things about CUPS is its browser interface. Point your browser at localhost:631 and you have pretty good control of CUPS. It isn't quite as good as you can get at the command line, but it's certainly a heck of a lot better than, for example, what Apple supplies to define and manage printers.

The browser interface certainly makes it seem to be possible to create a simple printer. It even shows the syntax you should use for printing to a file:

file:/path/to/filename.prn
 

However, if you actually try to use such syntax, it complains "client-error-not-possible". The same thing happens if you try to use lpadmin,

bash-2.05a$ sudo lpadmin -p fprint -E -v /tmp/xx  -m raw
lpadmin: add-printer failed: client-error-not-possible
 

and if you actually manually modify /etc/cups/printers.conf the printer just doesn't work.

Of course, I really didn't want to print to a file anyway. I really want to print to a script. The easy way to do that on System V is to print to a named pipe, and have a program that constantly reads that data, passing it on to a program. Well, it was beginning to look like this just wasn't going to happen with CUPS.

A Socket Printer

I had already added my Netgear print server to CUPS. That was easy:

sudo lpadmin -p laserjet6L -E -v socket://10.1.36.221:4010 -m laserjet
 

Since CUPS can very easily print to a network socket, I added a new printer:

sudo lpadmin -p tofile -E -v socket://localhost:12000 -m raw
 

Now all I needed was a server listening on port 12000. That's easy enough in Perl:

#!/usr/bin/perl
use IO::Socket::INET;
$myport=12000;
$pserve=IO::Socket::INET->new(LocalPort => $myport,Type=>SOCK_STREAM,Reuse=>1,Listen=>1) or die "can't do that $!\n";
while ($pjob=$pserve->accept()) {
  open(J,">>/private/tmp/x") or print "having issues $!\n";
  print J "New job...\n";
  while (<$pjob>) {
  print J "$_";
  }
  close J;
  close $pjob;
}
 

Obviously this is just the shell of what I really want, but it is the basic functionality: anything printed to "tofile" ends up in /tmp/x All I need to do now is write more code, which can be incorporated here or spun off to other programs.


If this page was useful to you, please help others find it:  





14 comments




More Articles by - Find me on Google+



Click here to add your comments
- no registration needed!

1. Create a new printer using the Printer Setup Utility. Give it the following characteristics:
- "IP Printing"
- Printer Type: "Socket/HP Jet Direct"
- Printer Address: "localhost:12000"
- Queue Name: "localhost:12000"
- Printer Model: "Apple"
- Model Name: "Apple Color LaserWriter 12/600 PS v2014.108"

2. Use the lpadmin utility to fix the URL, since the one the utility creates will be incorrect:
- lpadmin -p localhost:12000 -v socket://localhost:12000/

The jobs coming into the perl script will now be very high quality postscript, easily converted to PDF using any of the standard methods and look much better than the other PDFs did for me.

Thanks for the tip!


MacOSXMacosxcupstofile :

The "client-error-not-possible" when you attempt to add a file printer can possibly be avoided by enabling file printers in cupsd.conf or similar. This enables the printer to be set up and printed to. But mine never actually creates or appends to the specified file, sigh!


This MAY clarify the problem (or not)... an excerpt from the cups manual.

FileDevice

Examples

FileDevice Yes

FileDevice No

Description

The FileDevice directive determines whether the scheduler allows new printers to be added using device URIs of the form file:/filename. File devices are most often used to test new printer drivers and do no support raw file printing.


The default setting is No.

Note:
File devices are managed by the scheduler. Since the scheduler normally runs as the root user, file devices can be used to overwrite system files and potentially gain unauthorized access to the system. If you must create printers using file devices, we recommend that you set the FileDevice directive to Yes for only as long as you need to add the printers to the system, and then reset the directive to No.










Mon Mar 14 21:23:12 2005: 178   TonyLawrence

gravatar
Turns out that the easy way to do this is to edit /etc/cups/printers.conf and fix the line with the device to be whatever you want, but tell cups it's parallel:

DeviceURI parallel:/tmp/whatever

Restart cups and all is happy..



To add it that way to start with, use
lpadmin -p printername  -E -v parallel:/dev/whatever




Tue Mar 29 14:59:15 2005: 244   anonymous


The parallel way is the best for me, but remember that you must create first
the file,

> /tmp/myfile.prn
chmod a+rw /tmp/myfile.prn
and if cupsd is running with lp user then
chown lp:lp /tmp/myfile.prn

I miss LPRng. (may be better than cups??!)









Wed Jul 27 23:12:22 2005: 887   tlambert


All you need to do is add a new backend type "file" (run these commands as root):

cd /usr/libexec/cups/backend
cat > file
#!/bin/sh
#
# Stupid printer backend that just appends to the file "fee" in /tmp
cat >> /tmp/fee
^D

Then you have to make it executable:

chmod 755 file


Now you want to add a printer that uses this:

cd /etc/cups
cat >> printers.conf
<Printer foofile>
Info foofile
DeviceURI file:/tmp/doesntmatter
State Idle
Accepting Yes
Shared Yes
JobSheets none none
QuotaPeriod 0
PageLimit 0
KLimit 0
</Printer>
^D

Next, kick the cupsd:

killall -1 cupsd

Verify that it's there:

lpstat -p foofile
printer foofile is idle. enabled since Jan 01 00:00

Obviously, you can make the backend do whatever you want it to do. You could also pass it a file name as arguments using "job title" or whatever that CUPS passes to a backend.

-- Terry



Wed Jul 27 23:17:34 2005: 888   tlambert


Other examples live here:

http://users.phg-online.de/tk/CUPS/backend/



Thu Jul 28 10:57:22 2005: 892   TonyLawrence

gravatar
Yes, thank you. There's a reason why "The Hard Way" was part of the title: Cups has very poor documentation and I hadn't grokked the backend concept when I needed this feature.

There are several other articles here dealing with Cups, but I sure wouldn't mind seeing more. It's a good system, but suffers a little from "too much power". You can, of course, bypass all that confusion by using SysV style interface scripts ( http://aplawrence.com/Unixart/cups_sysv_interface.html ) when you don't need all the other stuff.



Sat Oct 15 22:12:17 2005: 1207   anonymous


You can use netcat as a socket listener then spool the printer output to the socket on which netcat is listening.

nc -l -p9100 >filename.out

I have found netcat to be very useful in capuring and redirecting print output streams.



Wed Jun 14 14:00:37 2006: 2113   YDurant


you could add FileDevice YES to cupsd.conf to allow printing to a file from cups.



Wed Jun 14 14:11:15 2006: 2114   TonyLawrence

gravatar
Yeah: that's all discussed above.



Wed Jul 2 22:02:34 2008: 4388   SimonBunker
http://rendermania.com

Thanks for writing this. Particularly useful was finding out about the backend filters. They really do make this sort of thing easy. I have used this to create a render farm for rendering 3d animations - the details are here: http://rendermania.com/building-a-renderfarm-with-cups/



Fri Oct 30 17:59:12 2009: 7386   Boborama

gravatar
I was able to use these tips to create a "print to file" that I tested with "lp -d printername testfile" It does create my "file" in the tmp directory but won't "append" to build a continuous stream. I need a "printer" that just builds a never ending stream. I built the dummy "backend device" which just doesn't seem to work for me. Best I can seem to get is every time I print... the file is overwritten with the new job.



Fri Oct 30 18:10:39 2009: 7387   TonyLawrence

gravatar
If you used ">>", it should be appending.



Sat Oct 31 02:42:54 2009: 7394   boborama

gravatar
Yes, I understand UNIX fairly well. When I execute the backend script from the command line and type some text ^D to exit. It DOES get appended to my tmp file. I just can't seem to get any results when I set the DeviceURI = to the backend script. The Word "file:" seems to work even though I have no backend script called "file" (works with the overwrite behavior). If I supply a nonexistant backend name like "gibberish" checking the status of the printer tells me that the backend does not exist. When I change it to my custom backend... it reports that it's idle and enabled. Printing to it produces nothing. maybe I'll change the backend to "echo hello world" and see if that works. Thanks for the feedback.






Sat Oct 31 03:12:47 2009: 7395   boborama

gravatar
I changed my backend to append an echo of "hello world" and that worked fine. It would seem then that the backend is indeed executing...but it's not "receiving" a stream of text for "cat >>" to act upon. I changed the script to echo out the incoming parameters from CUPS and received some nice output "114 reb test2 1 document-name=test2 finishings=3 number-up=1 job-uuid=urn:uuid:78d63f83-7e4a-3dc1-605b-cd4b77488939 /private/var/spool/cups/d00114-001" basically the job number and file name etc. Maybe I need to grab the parameters and cat with append what appears to be the spool job path. Don't get me wrong your article has saved me a ton of time pouring over and deciphering a CUPS manual for what ought to be a simple thing to do. Many thanks.






Sat Oct 31 11:12:07 2009: 7396   TonyLawrence

gravatar
Huh?

This is not a backend script. This is a socket printer with a background script listening at the port.

Don't miss responses! Subscribe to Comments by RSS or by Email

Click here to add your comments


If you want a picture to show with your comment, go get a Gravatar

Kerio Samepage


Have you tried Searching this site?

Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more. We appreciate comments and article submissions.

Publishing your articles here

Jump to Comments



Many of the products and books I review are things I purchased for my own use. Some were given to me specifically for the purpose of reviewing them. I resell or can earn commissions from the sale of some of these items. Links within these pages may be affiliate links that pay me for referring you to them. That's mostly insignificant amounts of money; whenever it is not I have made my relationship plain. I also may own stock in companies mentioned here. If you have any question, please do feel free to contact me.

I am a Kerio reseller. Articles here related to Kerio products reflect my honest opinion, but I do have an obvious interest in selling those products also.

Specific links that take you to pages that allow you to purchase the item I reviewed are very likely to pay me a commission. Many of the books I review were given to me by the publishers specifically for the purpose of writing a review. These gifts and referral fees do not affect my opinions; I often give bad reviews anyway.

We use Google third-party advertising companies to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, click here.

pavatar.jpg

This post tagged:

       - CUPS
       - Code
       - Linux
       - MacOSX
       - Networking
       - Printing
       - Programming
       - Unix



















My Troubleshooting E-Book will show you how to solve tough problems on Linux and Unix systems!


book graphic unix and linux troubleshooting guide



Buy Kerio from a dealer
who knows tech:
I sell and support

Kerio Connect Mail server, Control, Workspace and Operator licenses and subscription renewals



Click and enter your name and phone number to call me about Kerio® products right now (Flash required)