Fast personal printing _without_ CUPS

Ronald F. Guilmette rfg at tristatelogic.com
Thu Oct 27 08:28:32 UTC 2011



This isn't really a question.  It's more of a semi-rant, combined with some
information that I wanted to put on the record (so that it can be googled)
because it may benefit some folks, other than just me.

I'm impatient by nature, and I don't like CUPS.  (I would say that I hate
it, but I don't actually feel that strongly.)

I have two personal workstations.  When I say "personal" I mean it.  I'm
the only one who ever touches them.

One of them I have been bringing back up recently after a long hiatus,
and I've just installed 8.2-RELEASE/amd64 on it.

One of the first things I found I needed to do with it, after installing
the OS and a bunch of my favorite ports & packages was to set it up for
printing to a crusty/trusty old workhorse... an HP Laserjet 3015.  (This
printer can print both plain text and Postscript, but if I just send
it plain text the output doesn't really suit me, so I've made it prettier.
See below.)

Because I've never used 8.2 before... or even any 8.x release, I naturally
went into the Handbook and looked for _current_ guidance on setting up
printers.  Most of that information was quite helpful, right up to the point
where it started discussing CUPS.

The bottom line is that CUPS is sophisticated, which is to say complex and
convoluted.  If you are impatient, then setting up CUPS properly is both
tedious and time consuming.  Of course, it _is_ essential that you properly
set up CUPS if you are setting up a _server_ that multiple people will use,
but for a personal workstation, the entire queueing structure is just overkill,
in my opinion.

More importantly, CUPS, for me at least, seems to be quite slow.  There's a
loooooooong pause after I queue something for printing until something actually
comes out of the printer.  Maybe that's my fault, e.g. because I didn't con-
figure CUPS correctly, and maybe it isn't.  I don't know, and actually, I
don't want to know, because I found a way to nicely print stuff that just
bypasses CUPS entirely.  And it works for me, so I am a happy camper.

I just wanted to share what I did.

In a nutshell, I moved/renamed /usr/bin/lpr to /usr/bin/lpr- and replaced
it with this trivial script:

============================================================================
#!/bin/sh

printer='/dev/ulpt0'

if [ $# = 0 ]; then
  cat | /usr/local/libexec/psif > $printer
else
  for arg in $* ; do
    cat $arg | /usr/local/libexec/psif > $printer
  done
fi
============================================================================

My Laserjet 3015 used to be hooked up via a good old fashioned bulky "centronix"
parallel cable, but I thought that I ought to finally get myself into this
century, so I got a new USB 2.0 cable for it just the other day, and now it's
name is "/dev/ulpt0" rather than "/dev/lpt0" as before.

As you can see, the script above just takes whatever filnames are given on
the cmmand line and cats them one-by-one through psif and then the output
from that gets sent straight to /dev/ulpt0.

One little snag though... as I found out, it doesn't matter if you try to
set the SUID bit on this script and make it owned by root.  Nowadays shell
scripts simply do not do SUID anymore.  The only reason that's even signifi-
cant is that you'll probably want to be able to print while logged in as
any old user, and in order to make that work with this scheme, you have to do:

   chmod 0666 /dev/ulpt0

so that any user can write to the printer device file.

I only fiddled a couple of other small things in order to make this all work.
Firstly, I created my own versions of /usr/local/libexec/psif-text and also
/usr/local/libexec/psif-ps.  Here they are:

/usr/local/libexec/psif-text:
=============================================================================
#! /bin/sh

/usr/local/bin/textps -c 10 -l 60 -m 38 -t 46 && printf "\004" && exit 0
=============================================================================

/usr/local/libexec/psif-ps:
=============================================================================
#! /bin/sh

/bin/cat && printf "\004" && exit 0
=============================================================================

The parameters for textps that I have in my psif-text file were just some
parameters that I slapped together after running a few tests to see what
values created output that looked good to me.  Your milage may vary.

After I set up all of the above stuff, I noticed that my attempts to use the
"lpr" command to print things from non-root user accounts was still resulting
in very long delays before anything would print.  It took me some head scratch-
ing but I finally found the problem.  In a nutshell, the problems was that
at one point while I was trying to get this all going, I did in fact install
the CUPS package (and friends).  As I learned, when you do this you get the
following _different_ version of "lpr" installed in a place where normal user
accounts are likely to see it in their $PATH first:

   /usr/local/bin/lpr

Yikes!  So we've got /usr/bin/lpr _and_ /usr/local/bin/lpr.  I'm sure that at
some point, somebody thought that it was a good idea to have two radically
different programs in two different directories and give them both the same
name.  Maybe there actually is some good reason for that, but it wasn't
helping me any, so I just did:

   cd /usr/local/bin
   mv lpr{,-}
   ln -s /usr/bin/lpr ./lpr

That's all.

Now I can print either Postscript or plain text files to my LaserJet, from
both root and non-root accounts, and the printed output starts coming out
of the printer within just a second or two every time.  No queueing, no
fooling around, just push that document out lickety-split.

I'm sure that someone will tell me now that there are a zillion reasons
why I should not have done any of this, and that I just don't understand
this or that, or the fine technical reasons why CUPS is a wonderful tool
and why I should be using it.  But this works for me, and I saved a lot
of time by NOT having to learn all of the ins-and-outs of using CUPS or,
more importantly, configuring it.  (I'm sure its a fine package, but I have
other things that I need to be studying right now.)

The only thing that worries me about my rather ad-hoc way of setting up
a "personal" printer (as describe above) is that I sort of wonder what
will happen if I ever try to print something when something else is
currently printing.  (I did something similar to what I've described
above, but still rather different, back on my old 7.0-RELEASE system,
and I think that there, if the printer was already busy and I went to
print something else, then that second print attempt would just error
out right away.  Obviously, if you want to stack up a whole set of
documents for printing and then go out for lunch while they all print,
my cheap-man's approach to setiing up a printer, as described here, will
fail to give you the advantages of a real spooling/queueing system.  But
given that I personally rarely need to do that, for me it is pretty much
of a non-issue.)

That's all folks.  I hope this all may be of some help to somebody.

(Does anybody think that maybe this should go in the Handbook?)


Regards,
rfg


P.S.  While trying to debug my "slow printing" problem (see above) I did
some googling around and found at least a few other people asking about
this same sort of problem.  One of them even mentioned that, like me,
when he invoked "lpr" as root, the document gets printed immediately,
but then trying to do that same thing under any ordinary user account
results in this big delay before the printer prints anything.

Obviously, that guy also got bit in the posterior by the /usr/local/bin/lpr
versus /usr/bin/lpr issue/problem.  And I don't blame him for being puzzled,
as I was.  You don't typically get radically different outcomes... where the
main apparent difference is the _speed_ of the command... when you run
command `X' as root and then as non-root.  And that is only happening in this
case because we've got two totally different programs with the same name,
where one is in your default path if you are root, and a different one is
in your default path when you are non-root.

I'm not persuaded that giving these both the same name was really all that
good a choice, from a user-interace/human-factors perspective.  But I suppose
that it is far too late to do anything about those choices now.  Too much
other stuff has probably already been built assuming that things are this way.



More information about the freebsd-questions mailing list