Unix Printing

See the Printing FAQ also.

Most of what is covered here makes references to "interface scripts". Some people call them "printer drivers" (they aren't). These scripts are what controls what happens to your print job as it goes to the printer.


Hate these ads?

This information is for Sys V printing, specifically as implemented on SCO Unix. Linux printing uses a different scheme - there are articles at this site that reference Linux printing, but this is not one.

The scripts are found in /usr/spool/lp/admins/lp/interfaces (or /var/spool/lp/admins/lp/interfaces on modern systems, though the "old" path will still work). You will find that each of the printers listed by lpstat will have a script here, and the names will be the same as the name of the printers.

Note that if you are using HP JetDirect printers, the script will be there, but the actual script you want to modify is in the sub-directory "model.orig".

To make changes to interface scripts permanent, you want to make the same changes in the model script that was used to create the printer. The model scripts are usually in /usr/spool/lp/model, but it's possible for a printer to get its script from anywhere, so it's best to check. You can look in /usr/spool/lp/admins/lp/printers where you will find a sub-directory for each printer you have. Within that sub-directory is the file "configuration", and you can "cat configuration" to see where the script originated.

If you want your script changes to survive upgrades, copy them to a new name in /usr/spool/lp/model, and change the configuration file to reflect this, either by setting the model in the Printer Manager or by directly editing /usr/spool/lp/admins/lp/printers/yourprinter/configuration.

Topics covered here:






Printer doesn't work at all

Printer complains about tcgetattr failing

Printed output garbles after several pages

Printer faults and then reprints same document over and over

Last page of report doesn't print

Those header and trailer pages that won't stop printing

Those extra form feeds that spit out blank pages

Printer doesn't feed until you press Form Feed or Continue button

Stopping a print job and restarting it from the beginning

Grabbing the file before it prints

Other sneaky things you can do in an interface script

Stopping staircase output

Printing Postscript files

What Interface Script do I use?

Wrapping one printer in another

Controlling the default printer

Mixing Synchronics and Realworld or other mixed marriages

Making a network printer into a direct device

Transparent or pass-through printing

Also see: /Unixart/netprint.html


Printed output garbles after several pages

This is flow control. The computer and the printer have not made the proper arrangements so that the computer can know when to pause to let the printer catch up.

There is another article here on serial printers. You aren't likely to see this problem on parallel printers, though a bad cable can do this.

Also see Jeff Liebermann's Serial Printing article.

Last page of report doesn't print

This shouldn't happen on modern Unixes, but if you do have this, you can try adding "sleep 30" (or even longer) at the very end of the interface script.

The problem was that the script would end before all the output had been sent out through the driver. The kernel would see that that no process was using that data, so it would flush it away. Adding the "sleep" keeps the script from exiting, hopefully long enough for all the data to get out. If not, increase it. Note that this doesn't cause you to wait longer for anything in the printing process if the sleep time is equal to the time it takes to print the last page.

Those header and trailer pages that won't stop printing

On older systems, you were supposed to be able to just modify /etc/default/lpd and change it so that it read "BANNERS=0" and that would take care of it. On Unix systems, *sometimes* setting it to BANNERS=nobanner was the supposedly correct thing to do, but not usually.

Some printer scripts work from default/lpd even now, but some don't, and that can be annoying.

On Release 5, you are supposed to be able to choose Advanced settings from the Printer Configuration manager, and set the number of banners to 0.

The problem is that some of the interface scripts that SCO provides don't respect or even check the settings in /etc/default/lpd, and although most of the modern ones respect the setting from the Printer Manager, there are no guarantees. Do try the simple ways first. If you have a current version, you should be able to modify this completely within the printer manager. But, if that doesn't work (perhaps because you have third party scripts) you need to modify the scripts themselves.

You'll need to modify the scripts to take away the banners. Unfortunately, there are differences between the scripts, and even after that, there is still more work you'll have to do to make the changes permanent.

To begin with, search in the script for "banner=" at the start of the line. You can do this in vi by typing "/^banner=" and pressing enter. If you find nothing, try "/^nobanner=". If you still find nothing, try "/^BANNER".

Most of the scripts will say :

banners="yes"

On these, you want to change the "yes" to "no". But watch out: some scripts (the HPLaserJet for example) need it to be

banners=""

You need to read more of the script to see if that is the case.

Unfortunately, some scripts say:

nobanners="no"

and on these, of course, you must change "no" to "yes".

A few scripts might have:

BANNERPAGE="yes"

This, of course, requires a change to "no".

Some scripts expect that a variable will be passed to them in the environment. These generally test something like this:

if [ -z "${BANNERS}" ]
then
        nhead=1
else
        nhead=${BANNERS}
fi

For these, you'd set "nhead=0" after this section of the script. You should also be able to accomplish this from the SCO 5 print manager by setting the BANNERS setting to 0, but editing the script is absolute. Some of the scripts are really dumb about all of this.

It is entirely possible that you may have a script that does not use any such variables, but just blindly prints headers and or trailers. In such cases, you need to find where it's doing the printing and comment out those lines by putting a "#" ahead of them. If you are not sure what to comment out, you might be better off replacing this script with something more user friendly from /usr/spool/lp/model. Be sure to make a safe copy first, though. Having unwanted banners is better than not printing at all.

LPD printers are another story all together. Roberto Zini offers the following:

We had a customer who was lazy enaugh not to specify the
'nobanner' option along with the lp(C) command: for every
print job submitted a banner page got printed too and the
customer was not pretty happy about it (he already tried by
inserting the "BANNERS=nobanner" parameter in /etc/default/lpd
but unsuccesfully.

By following the printcap(SFF) manual pages, he inserted the 
'sh' parameter in the line remote printer line: that should
tell lp(C) to add the 'nobanner' option on its command line
but it didn't work. So, to ease his pain, I wrote the following
lp "wrapper" script, which actually did the job:

=== cut here ===

#!/bin/sh
#
# Faked lp(C) frontend to fool the lp(C) subsystem when
# it's unable to process the 'sh' flag in the /etc/printcap file.
#
# This file should be placed under /usr/bin and replaces the
# original lp(C) file which gets renamed as lp.orig; please
# set this script permissions accordingly to the original
# lp(C) ones.
# (chmod 2111 lp)
#
# R.Zini - Strhold (22/03/2000)
#

MLPDEF=`lpstat -d | awk '{ print $4 }'`
MYOPTS="$*"
MYPRT=""
MYBAN=0
MYDEF=""

#
# Grab the '-d <printer>' option; if it's not given, use the
# the DEFAULT destination printer.
#

while getopts :d: a
do
        case $a in
                d)      MYPRT=$OPTARG;;
        esac
done

#
# Do we have to use the default printer ?
#

if [ "Z$MYPRT" = "Z" ]
then
        MYPRT=$MLPDEF
        MYDEF="-d $MYPRT "
fi

#
# Check if we have to give the '-onobanner' option;
# in the /etc/printcap file the administrator has to insert
# the 'sh' flag for this trick to work.
#

grep ":rp=$MYPRT:" /etc/printcap | grep "sh" 1>/dev/null 2>&1 && MYBAN=1

if [ $MYBAN -eq 1 ]
then
        exec lp.orig $MYDEF -onobanner $MYOPTS  
else
        exec lp.orig $MYDEF $MYOPTS
fi

=== cut here ===

It's a "quick & dirty" script and perhaps it should be
rewritten by making use of a more consistent style
(I'm not that good at shell programming) but I've
been told that it suited my customer's needs.

Those extra form feeds that spit out blank pages

The concept here is the same as for getting rid of banners and trailers, but the scripts are even less standardized. The best place to look is in the section that (usually) starts with:

for file in $files

Following that maybe a line that does:

echo "\f"

or perhaps:

echo "\014"

or (less likely):

echo "^L"

and sometimes something obvious like:

echo "$formfeed"

Your job is to stop that formfeed from echoing. Some of the more complex scripts even have a whole separate formfeed program that they call. Whatever it is, if it's controlled by a variable set earlier in the script (most scripts are this way, including the Laserjet scripts), you should change that variable.

Remember that HP Jet Direct printers have the real script in model.orig (see the first section of this article) and that you need to modify the models if the change is to be safely permanent.

Examples: the "dumb" and "hp" models have this code around line 100:

        for file in $files
        do
                0<${file} eval ${FILTER} 2>&1
                echo "\014\c"
        done

You'd need to remove the "echo "\014\c" line, or comment it out:

        
              # echo "\014\c"
        

There's another "echo" a few lines above; this is the one that spits out before your print job.

However, in the "standard" model, you'll find this around line 289:

nobanner="no"
nofilebreak="no"

Just as you would change "nobanner" to "yes" to stop banners, you change "nofilebreak" to "yes" to prevent extra blank pages. Hans Fuller (hans@fullermetric.com) reminds me that if an HP script isn't already doing an echo "\033E\c" , you should replace the "\f\c" with that to reset the printer.

No Form Feed

Sometimes people complain of the opposite problem: they want form feeds and aren't getting them. The answer for this is just the opposite of what was covered above: either add "\f" at an appropriate place or, if the interface has settings for filebreaks, use that.

I like to have a file /usr/lib/Control_L for use with netcat or when sending to remote printers.

To create /usr/lib/Control_L, do:



echo -n ^L  > /usr/lib/Control_L                                             # type Ctrl-L


You really need to TYPE Cntrl-L (hold CTRL and press L). When you do that your screen will blank. Just keep going with the ">" etc.

You'd use this like:



cat "$file" /usr/lib/Contol_L |  lp -dcprod 1>/dev/null 2>&1
or
cat $* /usr/lib/Control_L | netcat -h printserver -p 9100


See http://aplawrence.com/SCOFAQ/scotec7.html#getnetcat also.

Stopping a print job and restarting it from the beginning

When pages jam, it is sometimes a major job to re-print the job. Fortunately, it's pretty simple to starts a job over if it has not already all spooled into the printer's buffer.

The very first thing to do is turn the printer OFF-LINE. That's usually done with a ON-LINE or SELECT button.

Now type "disable printer", or "disable hallway", or whatever the name of your printer is.

Now turn the printer OFF. This will flush out whatever is in it's buffer. Turn it back on, and adjust the top of form on tractor feed models if necessary. Finally, "enable printer", again, using the name of your printer.

(If you don't know the name, "lpstat -t | more" should help you).

Grabbing the file before it prints

Sometimes you want the results of a print job so that you can e-mail it to someone else, import it into a Word Processing document or whatever. This is simple to do.

Put the printer OFF-LINE as described above. Alternately, if you have not yet printed, "disable" the printer (see above). Now

cd /usr/spool/lp/temp
l [0-9]*-* | more

You will see something like this:


ad
rw-rw---- 1 lp  lp   71 Dec 1 09:15 178-0
rw-rw---- 1 lp  lp   83 Dec 1 09:16 179-0
rw-rw---- 1 lp  lp 7809 Dec 1 09:15 179-1

Your dates and sizes will be different, as will the names of the files.

These files are information about what is to be printed and how. For example, if you looked at that 178-0 file on my machine, you'd find it contained:

C 1
D myprinter
F /etc/passwd
P 20
t simple
U root
s   0000
l C_C.C
m C_C.C

while the 179-0 had this in it:

C 1
D myprinter
F /usr/spool/lp/temp/179-1
P 20
t simple
U root
s   0000
l C_C.C
m C_C.C

Notice the difference between the two. You might have already guessed that the "C" line is the number of copies, the "D" is the printer it's going to print on, and the "U" is the user who printed it. The "F" is the file that will be printed, and if it was generated as the result of program output (as opposed to "lp /etc/termcap"), it will refer to another file in this directory.

If you have more than one print job, you might not know which file is the one you want. If the size of the -1 files combined with the destination and user isn't enough to help you, then examine each -1 file in turn. Once you have what you want, copy the file wherever you want it. If you don't want it to print after that, cancel it. For example, I might say:

cp /usr/spool/lp/temp/179-1 /tmp/printfile
cancel myprinter-179

Other sneaky things you can do in an interface script

Actually, you can do whatever it is you need to do. You can grab the data that is going to the printer and send it off to another printer; you can invoke stream editors like sed or awk or write a Perl script that will change the data before going to the printer; you can strip off all but the TOTAL line from a large report, or whatever it is that you need or want to do. The possibilities are only limited by your imagination and your programming skills.

As an example, I had a customer who wanted to keep a log of invoices printed. The accounting software somehow neglected to provide this very basic function. To solve this, we changed things to look very much like this:


        for file in $files
        do
                0<${file} eval ${FILTER} 2>&1
                head -5 $file | grep "INVOICE" >> /logs/Invoices
        done

The actual implementation was a little more complex (we wanted some additional data that would be found on other lines in the file), but the concept is identical.

You can make one script serve double duty. For example,

RealWorld and Synchronics are two popular accounting packages that often complement each other and are found on the same system. Unfortunately, each package has very different ideas about form-feeds at the end of print jobs, and some reports should go landscape, etc. and installers often end up creating two or more printers to the same device to handle this. It's unnecessary: pass the appropriate option to the printer. Both of these packages define the lp string to be used, so you can define it as "lp -s -dprinter1 -o whatever-you-need".

Wrapping one printer in another

You can also have a printer that sends its output to another printer; pipe the final output to lp -s -dotherprinter You'll probably want the first printer's device to be /dev/null, but consider that it does not have to be: you can have a printer that prints to multiple places at the same time.

This scheme can be very useful for network printers that use lpd. Rather than trying to pass options through, front end with a script that does whatever needs to be done (like running it through /usr/lib/lponlcr) and then passes it to the lpd printer.

This is how you do "virtual" printers: many names all going to the same print device, but all with diferent options. This is often easier than handling all the testing for different switches inside one interface, and it gives you mnemonic names like "HPLandscape", "HPLetterTray", etc.

The easiest model to use for that is the "network" script. Let's say you want to actually send to "kyocera":

cp /usr/spool/lp/model/network
/usr/spool/lp/model/yourscript
vi /usr/spool/lp/model/yourscript
(add whatever you need and then)
/usr/lib/lpadmin -p wrapit -m yourscript -v /dev/null
/usr/lib/accept wrapit
enable wrapit
echo "wrapit: lp -dkyocera" >> /usr/spool/lp/remote

Now when you print to "wrapit", it will go to the kyocera carrying whatever you added in the script.

Controlling the default printer

Sometimes you want a person's default printer to be different than someone else's (the default printer is the one that gets used when you just use "lp" by itself). One way to control that is with LPDEST. For example, the following lines in .profile will set the default differently when logging in on different tty's:

DEFPRINT=`tty | sed 's/.dev.tty//'
LPDEST=biglaser; export LPDEST
case $DEFPRINT in
  A0[1-8]) LPDEST=printer_7;;
  A09) LPDEST=accounting;;
  0[1-9]) LPDEST=console_laser;;
  B*) LPDEST=ohio;;
  C*) LPDEST=california;;
esac

This assumes that the port being used determines the persons physical location. Sometimes you need to be even trickier than that, or you want to change multiple "printers" at the same time. Consider the case where you have multiple offices, but you want to have your software just use "checks" and "forms" so that the choices it presents aren't cluttered with entries like "la_forms", "denver_checks", etc. To do this, you need to front-end the lp program itself- you have a script that pretends to be "lp", but it decides where the job should really go and passes that to the real "lp" program. When it saw a request to print to "forms", it would decide what real printer to send to, and re-route it appropriately. Here's a post from Bill Vermillion describing a similar idea:

Newsgroups: comp.unix.sco.misc
Path: news.randori.com!feed2.onemain.com!feed1.onemain.com!isdnet!skynet.be!oanews!info.usuhs.mil!uky.edu!news.xenitec.on.ca!news
From: Bill Campbell <bill@celestial.com>
Subject: Re: How do I set default printers?
Resent-From: mmdf@xenitec.on.ca
Submit-To: scomsc@xenitec.on.ca
Content-Type: text/plain; charset=us-ascii
Reply-To: bill@celestial.com
Organization: [resent by] The SCOMSC gateway and Propagation Society
Date: Fri, 28 Apr 2000 18:17:50 GMT
Message-ID: <20000428111750.A6666@kstarr.celestial.com>
Mime-Version: 1.0
In-Reply-To: <qejjgso6poqtro30i606jfm5sbg8nrijf3@4ax.com>; from jeffl@comix.santa-cruz.ca.us on Fri, Apr 28, 2000 at 10:52:04AM -0700
References: <nYhO4.9849$9A6.55224@typhoon.tampabay.rr.com> <yJjO4.10289$9A6.56093@typhoon.tampabay.rr.com> <qejjgso6poqtro30i606jfm5sbg8nrijf3@4ax.com>
Sender: news@xenitec.on.ca (xenitec.on.ca News Administrator)
Precedence: list
Lines: 55
Xref: news.randori.com comp.unix.sco.misc:59126
X-Mozilla-Status: 8010
X-Mozilla-Status2: 00000000

On Fri, Apr 28, 2000 at 10:52:04AM -0700, Jeff Liebermann wrote:
>On Fri, 28 Apr 2000 17:18:22 GMT, "jmt" <jmtcode@hotmail.com> wrote:
>
>>I forgotten to mention if the running application has the printer name
>>hardcoded into there application to which printer to print to, how can I
>>change that printer? I know what the printer name is, just need to redirect
>>there print job to another printer name.
>
>If your unspecified application has something like:
>    lp -d printer_name
>imbedded in some configuration file, then you're stuck.  It takes priority
>over $LPDEST and over the print spoolers default printer.
>
>However, I know of no application, written by mortals, that cannot be
>twisted into doing what I want it to do.  First, find the configuration file
>that goes with your unspecified application, and see if you can find the
>place where the printer is defined.  If it looks like:

I have a system that does exactly that.  I have a file, /etc/printers
that has entries mapping logical printer names to real printer names,
and the system on which to print them.  The file looks like this:

default laser localhost
laser   laser localhost
oldprn  printer someotherhost
...

I then have /usr/local/bin/lp that's in the PATH before /usr/bin/lp
and further I move the original /usr/bin/lp to /usr/bin/lp.original,
and link it to /usr/local/bin/lp to make sure that everybody uses it.
My script then reads the /etc/printers file, and maps the printer name
to the real printer.  If the printer's local, then it forwards the job
to the local with a pipe to ``/usr/bin/lp.original -ddestination''.
If it's a different system, then it pipes to the remote system using:

        "|ssh someotherhost /usr/local/bin/lp @ARGV"

This is in perl so it passes the appropriate arguments to the remote
system's /usr/local/bin/lp program which goes through exactly the same
process.  It would even be possible to have the job get in a loop if
each system redirected the job to the other (I suppose this could be
done intentionally if there were a printer problem, breaking the loop
when the printer was working again :-).

The code you use to decide where to re-route can be as simple or as complex as you need it to be. It can be based on the serial port, or you could have exported an environment variable. You might even need to ask the user in their .profile which "set" of printers they want to use, or where they are presently located. Store that information in a variable and export it.

Stopping staircase output

Staircase is when you printer prints like this:

Everything starts out OK, but when you reach 
                                             the end of a line, it moves
                                                                         down but not back

This is caused by the different ways that DOS and Unix handle the end of a text line. Unix ends a line with a LF (Line Feed, 0x0A) character, while DOS uses both a LF and a CR (Carriage Return, 0x0D).

If a printer is expecting both characters, getting only a LF tells it to only do a Line Feed without a Carriage Return, so that's just what it does, and that's just what you get.

There are at least five ways to fix this:

  • Change the printer so that it generates a CR when it gets a line feed. Most printers can do this, and if you use it for DOS, it just means there is an "extra" CR, which changes nothing. This is done with dip switches or a printer configuration panel.

  • Change the printer by sending it whatever escape sequences it needs to add CR's to LF's. This is going to vary, and you are going to need to add it in the interface script low enough that it doesn't get reset by some other command being sent out.

  • Set the "stty onlcr opost" in the interface script. This can be done from the printer manager on Release 4 and 5, or by using the "crnlmap" model; unfortunately it does not always work (for example, it can't work for network printers). See: /Unixart/netprint.html

  • Move the "stty onlcr opost" to a "hold-open" script (see the article on serial printers) for this port. This works, but it's annoying, and again won't work for network printers.

  • Filter the output through /usr/lib/lponlcr. This involves piping the output through that on it's way out. In the "standard" script, you might set "FILTER=/usr/lib/lponlcr". In other scripts, just add " | /usr/lib/lponlcr" on the line that cats the file.

  • If you are using an HP network printer, you can add "-n" or even "-N" to the the interface.

    Don't add it to the "HPNPF=" line; add it in the line(s) that actually uses $HPNPF. For example, you'd change

        if $REALMODEL "$@" | $HPNPF -x $PERIPH 2> $LOG > /dev/null
    to
        if $REALMODEL "$@" | $HPNPF -x $PERIPH -n 2> $LOG > /dev/null
    

    See man hpnpf


David DiPieto offered these thoughts:

Date: Tue, 29 Dec 1998 16:05:40 -0500
From: David DiPietro <abacus@garden.net>
To: tony@aplawrence.com
Subject: printer stairstepping ...
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I thought I'd share a little opost experience with you.  When I install
our application software I automatically add a "holdopen" for each
parallel and serial printer to append the <cr> to <lf> as you mention in
your printer discussion.  Most of our sites now involve some kind of
networking and printer sharing.  I had been putting the high-speed
lasers on the parallel ports on the SCO Unix server but starting having
a problem with Windows applications printing graphics.  I would often
loose data or get garbled graphics.  I finally decided to take the time
to figure out what was going on using the hex dump mode on a Lexmark
Laser.  Apparently, and with understanding, having opost onlcr turned on
will do a straight binary filter of the printer data replacing all <nl>
with <cr><nl> - even if it occurs in the middle of a raster graphics
string.  This could - and will most likely - reak havoc on the output! 
You may want to address this in your discussion.  In my case, the
problem was solved completely by turning on the auto <cr> at the
printer.
Dave DiPietro/Abacus Systems Inc.
(973) 875-9900

Printing Postscript files

You do have a Postscript capable printer, right? OK, just checking, 'cause if you don't the first part of this is going to help you.

Try:

lp -o raw

or

cat filename | /usr/lib/lponlcr > /dev/printerport

If the second one works but the first one doesn't, your interface script is wrong, confused, or your printer needs stair-step handling ( see above).

If you don't have a Postscript printer, you might be able to use Ghostscript (available from SCO's Skunkware Page ) to get some functionality. Ghostscript is slow and has had a few problems now and then, but you might find that you can live with it.

You can install ghostscript from the Skunkware CD; don't forget that you also need the Glib (Graphics Library) package.

To see the printers that ghostscript supports, type

gs -?

You may have to experiment a bit to find out what works best with your printer; for example I found that "ljet4" was good for my LaserJet 6L. I suggest that you create a simple Postscript file for testing:

echo "testing" | text2post > /tmp/test.ps

With a large page, you may get page after page of junk on your printer- best to test with something small like this.

"text2post" is a script that converts simple text to simple Postscript. No matter what version of SCO you have, this script is somewhere on your system, though it may not be in your path. If necessary, try

find / -name text2post -print

To get it actually working after you get the right driver, you can either use a simple script:

#!/bin/sh
/usr/local/bin/gs -q -sDEVICE=ljet4 -r600 -sPAPERSIZE=letter -dNOPAUSE -dSAFER -sOutputFile="-" - | lp -dlaser -o raw

I call that "webprint", and once you've told Netscape to use it instead of "lp",that's what continues to pop up in the Netscape print dialog.

Or, you can get fancy and build gs support into your interface script, even to the point of automatically recognizing Postscript files. That can be a little tricky, and really has no advantage over the shell script, but some people like to do it that way.

What Interface script do I use?

That depends upon both the printers ability to emulate other printers and your need for special effects.

For example, the "dumb" and "standard" interfaces just send along characters. They don't know how to make things bold or change fonts; they just send out characters. Most dot-matrix and even quite a few lasers are quite happy with that, and will produce output that is entirely suitable for typical office reports, though perhaps not for word processing.

If you *do* need more control, you simply need to know what the printer can emulate, and choose the appropriate interface from that knowledge. Almost all printers emulate something, and in the rare case where they don't emulate anything useful, you need to get the control codes for the features you want from the manual, and then modify some other script.

Of course, that won't help with programs like Word Perfect that provide their own drivers and use the interface files only as a means of co-existing with other programs using the spooler. In that case, you either need to emulate something that Word Perfect or your other high level program can understand, or you have to settle for simple, no frills output.

Printer doesn't work at all

The first test is whether or not you can print to the raw device (if this is a network printer, see Network Printers). If you aren't sure about how the printer handles line feeds, do this:

/usr/lib/lponlcr > /dev/lp0

(assuming that your printer is /dev/lp0, of course). Type a few lines, and then press enter and CTRL-D. If it gets to the printer, then the port is fine.

The port does show up in "hwconfig", doesn't it? Type "hwconfig | grep parallel" or "grep serial" just to be sure. If it doesn't, you either never defined it (run "mkdev serial" or "mkdev parallel") or the definition is wrong: for example, you said it's a parallel port at 378, but it's actually at 278.

If this is a parallel printer, be sure that your BIOS has it set to "Standard Parallel Port" (sometimes it's "SPP"). If it's EPP, it will not work with current SCO Unix.

Similarly, there are some "Windows Only" printers that require EPP ports and Windows software- those just are not going to work, period. See Windows Printers for one way around this.

Note : Okidata serial printers require DSR Invalid when using 3 wire xon/xoff flow control. Set this on the printer, using the front panel menus.

If it just hangs, the interrupt is wrong or the card just plain doesn't work (and no, "it works in DOS" doesn't help). It's probably an interrupt problem; the port is never acknowledging receipt of characters so it hangs.

Understand that the "vec=" info in hwconfig for non pnp devices is just a parroting of what YOU told the machine the interrupt is. The lp or serial driver trusts you, but it doesn't really have a clue. It checks the address (378, etc.) by poking certain patterns into certain offsets and then reading the results; if the results are what a parallel or serial port should be sending, then it assumes it has a working port (see /Unixart/driverart.html if you really want to know the gory details). Whether or not the port works otherwise is not the job of the initialization routine, and it definitely is not going to check that interrupts are working or even correct.

Of course, you could have a bad cable, or even a bad printer. I had a customer recently who spend half of a day being very frustrated after an upgrade because he'd done everything right, had double and triple checked everything, but one printer wouldn't print. I suggested putting another printer in, and, yep, that was it: a printer that worked fine the day before had coincidentally died.

Check power, too: I once had a printer that would turn on; the panel lights worked and all that, but it wouldn't print. It turned out that we had only 80 volts at the outlet, and it wasn't enough to drive the motors (this was some years ago).


Windows

There are now Windows printers that require Windows software. These are generally less expensive units, and won't mention Dos or Macintosh or anything but Windows in their descriptions. At this moment, I don't know any way to have these work on Unix, but I did receive a great suggestion on this:

Date: Tue, 29 Dec 1998 16:05:40 -0500
From: David DiPietro <abacus@garden.net>
Reply-To: abacus@garden.net
Organization: Abacus Systems Inc
To: tony@aplawrence.com
Subject: HOST BASED PRINTERS
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I was looking for a solution to an lpstat hang problem in SCO unix with
TCP based printer server and I noticed you have a remark that you could
not get the "cheapo" windows printers to work from Unix.  I had a
conversation with an engineer at Lexmark recently about this. 
Apparently, due to some quirk in the HP PCL licensing agreements,
printer manufacturers must pay HP a royalty if they use PCL code in the
printer firmware.  If they use an emulation in the driver, however, they
do not have to pay the royalty.  So, manufacturers like Lexmark and
Cannon have developed their own machine language to communicate between
windows and the printer.  The windows driver converts the HP PCL
commands to their own machine language and uses that to drive the
printer.  Since the driver is specific to windows, the printer will not
work under any other operating system - including DOS.  A sure fire way
to check is to boot the machine to DOS and try a print-screen.  Note
that if you shell to DOS it will still print because the windows print
manager is still resident.  All this to save a few bucks!

I did find a way around this using a shared drive and an emulator that
lets you submit DOS commands from the Unix host.  We use a product from
April Designs in Sweden called Fusion95 to take the place of Advanced
File and Printer Server, and an emulator called ANITA from the same
company.  If you have never seen these products, check out APRIL.SE -
they have 30 day trial versions available for download.  

The way I get this to work is by modifying the standard or dumb model to
put the output in a shared directory on the server.  When the file is
done spooling, I issue a DOS COPY command to the emulator to COPY the
file to the printer port.  Since windows is active, the print manager
picks up the file and does the proper translation to machine code before
sending it to the printer.  

In the real world, I do not recommend that our users buy these host
based printers to use with Unix.  It would cost us more to support them
than the printers are worth.  With REAL laser's coming down in price,
why bother!

I hope I was able to provide you with some information you didn't
already have!

Happy Holidays,
David DiPietro/Abacus Systems Inc.
Sussex, NJ  (973) 875-9900

You could also use Visionfs or Samba.


Printer faults and prints same document over and over

The only time I've seen this happen is when some very old interface scripts were copied up to a new version. I never took the time to look at the scripts to see why they weren't working, but apparently they'd hang for some reason, so lp would assume a printer fault, stop the job, wait a bit, and then send it again. And again, and again.. Replacing the interfaces with current versions fixed it instantly.

Mixing Synchronics and Realworld or other mixed marriages

Sometimes mixing more than one program causes printer grief because one program adds form feeds to its reports and the other does not, so you have a nasty problem. It's usually not all that hard to fix, though; here's what I did for one customer with that problem:

Synchronics spooled printers are defined in the "synsuppl" file in the Synchronics directory (/syn on ssirw1). These take the form of:

dd_printername="lp -s -dhpjet5"; export dd_printername

What I did was add "-o syn" to each line:

dd_printername="lp -s -o syn -dhpjet5"; export
dd_printername

Next, I modified the interface scripts. For the hpjet printers, these are found in the directory /usr/spool/lp/admins/lp/interfaces/model.orig/ Each file there is the script that print jobs are processed by. Within the scripts, the options are extracted by a section that begins:


for i in $5
do
        case "$i" in

        -postscript | postscript)
                format="PS"
                outputmode="raw";;

I added a test for "syn" to this:

for i in $5
do
        case "$i" in

        syn)
                outputmode="raw" ;
                FILTER="sed '$d'";
                SYN="true";;
                
                
        -postscript | postscript)
                format="PS"
                outputmode="raw";;


Therefore the script acts this way ONLY if "-o syn" is used, which will only be for Synchronics. Further on in the script, I added a section that tests for $SYN being true, and there I set the lines per page to 66. Finally, the FILTER setting above deletes the very last line of the report, which contains an extra form feed I don't think we want. To disable this, just change

        syn)


to

        notsyn)


Transparent or pass-through printing

Many terminals, and just about all terminal emulators, have the ability to do "local" printing. It's sometimes called "transparent printing" or "pass-through", but the idea is that if the terminal sees a special key sequence, it will start sending the data out some other port (parallel or serial) until it sees some sequence that tells it to stop.

In general terms, it's a lousy way to print. If you can possibly do this any other way, you'll be much better off.

If you have an intelligent multiport card serving these terminals, the vendor may have provided a way to make this better (still not great, but definitely much better). Digiboard, for example, creates transparent print devices that match your tty id's- if you have terminals /dev/ttyb01 through /dev/ttyb16, you also have /dev/prb01 through /dev/prb16, and as long as you have told the Digiboard driver what escape sequence will start and stop the printing (common terminal types like ansi and wyse60 are configurable by name), the driver will do a nice job of handling this for you: anything directed at those "pr" ports will get printed.

If you don't have something like this, you use commands like "lprint" (SCO OSR5) or you wrap your data in the start-stop sequences yourself.

Printer fails and complains about tcgetattr

You have a network printer ( or a virtual printer pointing at /dev/null ) but you've left "stty" statements in the interface script. Comment them out.

Making a network printer into a direct device

This is sometimes needed for applications that insist upon using devices, either because they have no way to use Unix spoolers or because they think they need a direct device for some other purpose.

The basic concept is to create a named pipe. For example, you might do this:

mknod /dev/myfakenetprint p

That creates a "device" that your application can print to. Use "chmod" as necessary to give it whatever permissions you need (666 if everyone needs to use it).

Now you need something that runs all the time in background. It's a shell script (see New to Unix if you don't know how to make a shell script) and it needs to start automatically whenever the machine is rebooted (see Automating Program Startup). This script assumes that your network printer already exists in the spooler:

while true
do
cat /dev/myfakenetprint | lp -dmyrealnetprinter
done

You could also use hpnpf or netcat (see Network Printing ) directly:

while true
do
cat /dev/myfakenetprint | netcat -h printername -p 3001
done

These work because the "cat" will hang until something (your application) writes data to the named pipe. The "lp" won't complete until cat is done reading, which will be when your application closes its writing. Although it might look like this ties up your cpu, it doesn't- the cat sleeps while it hangs, and so does lp or netcat: there's nothing going on until you write data to the named pipe.


M3IP inc.

BF Printing has some other useful printing links.


© 1998, 1999 Anthony Lawrence. All rights reserved.




Enter your email address for automatic notification of new posts here
(be sure to whitelist 'feedburner.com' if you use spam filtering)

Or use any RSS reader

Delivered by FeedBurner


LOD Communications, Inc.

Views for this page
Today This Week This Month This Year  Overall
7442044,076 41,617

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

pavatar.jpg
More:
       - Printing
       - OSR5




Unix/Linux Consultants

Your ad here - $48.00 yearly!

http://bcstechnology.net Full service Linux & UNIX systems integrator; Windows to UNIX/Linux Client-Server Specialist; Secure E-Mail & Website Hosting; Thoroughbred Software Developer; Custom Industrial Automation; Hardware & Electronics Experts; In Business Since 1985.


larryi@ccamedical.com SCO OS5, Debian Linux, RedHat Linux, MySQL, Apache, AJAX development using dXport/dL4/Unibasic, Windows Connectivity, Sharing Resouces, Automation, Shell Scripting


http://echo3.net/ Unix/Linux Custom Applications, Web Hosting, C/C++ Programming Courses



Twitter
  • Nov 18 20:41
    I'll be out all day Wednesday the 19th, hard to reach even by phone. Leave a message and have patience.
  • Nov 18 10:07
    What am I doing? Not doing what I WANT to be doing! Oh, well, in every life a little work must fall..




card_image








Change Congress


Related Posts