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

Unix SysV Printing

© July 2013 Tony Lawrence
January 1999

See the Printing FAQ and Serial Printers 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.

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

UUCP Printing

Creating a class of LPD printers

SysV Print Filters

Where do I find escape coes for HP printers?


Virtual PC Ports


Restrict access to specific printer

Also see: /Unixart/netprint.html

Printed output garbles after several pages

This is usually 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.

However, here's a case where Lexmark Se 3455 printers needed an MTU change..

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 :


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


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

Unfortunately, some scripts say:


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

A few scripts might have:


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}" ]

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 ===

# 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 }'`

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

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

# Do we have to use the default printer ?

if [ "Z$MYPRT" = "Z" ]
        MYDEF="-d $MYPRT "

# 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 ]
        exec lp.orig $MYDEF -onobanner $MYOPTS  
        exec lp.orig $MYDEF $MYOPTS

=== 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
                0<${file} eval ${FILTER} 2>&1
                echo "\014\c"

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:


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
cat $* /usr/lib/Control_L | netcat -h printserver -p 9100

See https://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:

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

You can figure out whether it is an app or the interface that is screwing things up by disabling the printer ("disable printer-name") and then printing. Examine the file(s) in /usr/spool/lp/temp. You'll find them named xyzxx-0, xyzx-1, etc. The -1's are the print jobs. Now send them directly to one of your printers:

cat *-1 > /dev/ttya01 (or whatever your printer port is).

If they all look good, it's your interface script that is causing the problem.

lpr job number

By the way, you can capture the job number when you print:

x=`lp -dtestprinter`

would put something like "request id is testprinter-513 (1 file)" in $x, so

x=`lpr -dtestprinter  | awk '{ print $4 }'`

will get you the job-id in $x (Unix or Linux).

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
                0<${file} eval ${FILTER} 2>&1
                head -5 $file | grep "INVOICE" >> /logs/Invoices

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
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;;

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 :-).

Obviously you could use "who" or "w" in simple cases.

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:

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
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.

People get confused by Postscript and PDF. This Adobe page explains what PDF is, but the confusion often comes when trying to print.

Unix systems understood Postscript early on because high end printers understood Postscript natively - just send them a Postscript document and they could print it. That's often NOT true today except for more expensive printers.

SOME printers can handle both Postscript and PDF's natively. For everything else, the PDF (or Postscript) needs to be run through a translator (to PCL commands, for example).

Both CUPS and LPRng should be able to translate PDF to whatever your printer needs. As this newsgroup post about commandline PDF printing explained, that should be automatic with CUPS and requires a bit more work for LPRng.

System V systems like older SCO have nothing built in to do the translation (though you may still be able to find Ghostscript; see How can I print from Netscape without a Postscript printer?).

If your printer DOES handle Postscript, PDF and PCL natively, of course it is a waste of time and resources to use Ghostscript to translate. I've seen this done either because people didn't know the printers capability (odd, considering that these tend to be expensive) or because they did not realize that CUPS was configured to translate.


lp -o raw


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:

/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).

I'm assuming that your interface script is not at fault - if it has been changed (check the ls -l date), that's worth checking.


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
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

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
        case "$i" in

        -postscript | postscript)

I added a test for "syn" to this:

for i in $5
        case "$i" in

                outputmode="raw" ;
                FILTER="sed '$d'";
        -postscript | postscript)

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




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.

See How do I do Transparent or pass-through printing (slave printing)? also.

UUCP printing

Sometimes a printer would be located somewhere accessible only by dial-up modem. The print spooler would cause uucp to dial and and connect to the printer. The printer type would be uucp dialup. Although uucp would guarantee that the job got sent, I'm sure you can imagine that there were many problems!

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
cat /dev/myfakenetprint | lp -dmyrealnetprinter

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

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

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.

Creating a class of LPD printers

Printer classes are an under-utilized feature (Linux cups has this also). What this lets you do is specify a group (the "class") and a job sent to that group will print to whatever printer in the group is available.

What if you want to put a group of remote LPD printers into a class? That is a bit unusual, but lpd printers don't support classes.

SCO systems have a mix of System V and LPD printing. The two aren't happily joined, and earlier SCO versions particularly lacked the ability to put any scripts or filters into LPD printers. However, having Sys V printing available (scripts in /usr/spool/lp/admins/lp/interfaces) meant you could get this by front-ending the LPD printer with a Sys V virtual printer.

You can do anything you need to do using the concept of virtual printers- a local printer that redirects itself elsewhere. SCO's Sys V side supported printer classes, but the LPD side did not. Set up several of these as virtuals that end up going to the Windows servers, put them in a class, and you have what you want. Another advantage of this for LPD printers is that you get to use any interface script you want.

I think the easiest and most maintainable way to do virtuals is to follow the same sort of scheme the hpnp uses but modify it with the "network" model: use an upper level interface like the one in /usr/lib/hpnp/model that filters output through a standard interface in interfaces/model.orig, but have it pickup the remote that it finally pipes to from /usr/spool/lp/remote like the network model does.

The same concept can be used with Linux CUPS

SYSV Print Filters

Print filters are a little used feature of Sys V printing. These are actually quite powerful and can allow for such things as printing only specific pages, handling printer faults, or converting specific input types to something the printer knows how to handle.

Unfortunately, the SCO manual page for print filters is a bit vague.

One of the other things to know is that if you have a filter, lp will accept other option flags that will be passed to your filter (if you do NOT have a filter, the job will fail if these options are used).

-y mode : mode is up to you, might be "color", "nocolor" or whatever your filter understands.

-P pagelist : Let's you select specifc pages to print. I've never tried this; it's not clear from the manual whether lp selects the pages or your filter has to do that work. A Sun man page says:

Each page range consists of a pair of numbers separated by
a dash, or a single number. (For example, 1-5,6,8,10
indicates pages 1 through 5, plus pages 6, 8, and
10.) However, whatever value was given in the -P option
to a print request is passed unchanged.

That would seem to imply that lp does the selection, but then why do you need a filter? Confusing..

SCO happens to include an example in their man pages and a ksh script (/usr/spool/lp/bin/pages) that clears up the mystery - your filter needs to do the selection processing. I'm not sure anyone has ever used it, but there it is.

The most important thing to glean from this newsgroup post is the part about what "printer accept types" mean - the only time you'd mess with that is, for example, when you have a printer that already knows how to handle either Postscript or PCL automatically. Otherwise, don't touch that.

Newsgroups: comp.unix.sco.misc
Subject: Re: print filters
From: spcecdt@deeptht.armory.com. (John DuBois)
Message-ID: <Xeke4.16029$7L.718133@tw11.nn.bcandid.com> 

In article <38797A88.423347FF@squonk.net>,
Brian K. White <linut@squonk.net> wrote:
>created a filter script that works the way the manual says it should. IE it
>takes user data on stdin and outputs printer data on stdout. I copied it to
>/usr/spool/lp/bin/ps2epson and made it's perms/ownership match the other files
>there, and tested it for basic functionality by catting a file through it just
>to be sure.
>here is the filter script
>exec /usr/local/bin/gs -q -sDEVICE=epson -r180 -dBATCH -dSHORTERRORS -dNOPAUSE
>-dSAFER -sOutputFile="-" -
>tested with: cat golfer.ps |/usr/spool/lp/bin/ps2epson >/dev/ttya08
>and it printed fine
>created this filter description file for use with scoadmin or lpadmin:
>Input types: ps
>Output types: any
>Filter type: slow
>Command: /usr/spool/lp/bin/ps2epson
>tried both scoadmin and lpadmin
>in scoadmin-->printers-->printer manager
>I selected system-->filters-->new
>and added a new filter named "ps2epson" and entered filename "/tmp/ps2epson"
>It _seemed_ to like it. *shrug* the new filter is listed in the filters box,
>and if I select "examine" it shows me a copy of the description file I made.
>then I select the printer I want to use this filter with ("p4") and select
>"settings-->advanced-->content types"
>the only content type listed at first is "simple"
>I select "define new" and type in "ps", then select "add"
>now ps is listed in both the defined and supported boxes for printer p4

By adding 'ps' to your printer accept types, you've told the print system that
it knows how to print a file of type 'ps' directly.  Therefore it does not use
your filter when you give it a ps file.  What you need to do is specify that
your filter produces output of a type specific to the printer.  Here's what I

input types: postscript ps
output types: epson
filter type: slow
command: /usr/spool/lp/bin/ps2epson
options: MODES draft = -d,MODES low = -d

Then specify that your Epson printer accepts the 'epson' type (and *not* ps).
Now when you use -Tps, the print system finds that there is no printer that can
print your file directly, but there is a filter it can use that will transform
the input type (ps) into an output type (epson) that one of your printers can

Oh, here's ps2epson:
# @(#) ps2epson 1.0 92/09/04
# 92/09/04 john dubois (john@armory.com)

while getopts :d opt; do
    case "$opt" in
    d) device=epson;;
    ?) print -u2 "Usage: $0 [-d] [file ...]"; exit 1;;

shift $((OPTIND-1))
if [ $# -eq 0 ]; then
    # Use stdin if no files named
    set -- -
    # If files given, close stdin so that interpreter won't go interactive
    exec < /dev/null

# Make normal output go to stderr & printer output go to stdout
gs -dSAFER -dNOPAUSE -dQUIET -sDEVICE=$device \
-sOutputFile=/dev/fd/3 "$@" 3>&1 1>&2

John DuBois    spcecdt@armory.com.    KC6QKZ   https://www.armory.com./~spcecdt/

From: kbs=cusm@shady.com (Kevin Smith)
Newsgroups: comp.unix.sco.misc
Subject: Re: print filters
Date: 10 Jan 2000 11:20:37 -0500

I've setup filters on Unixware but not exactly like you're doing but
I may have some insights.

First, I think the '-T<type>' may not be what you expect.  From the manual

    Tell the print service to print the request on a printer that
    supports files of the specified content type. If no printer accepts
    this type directly, a filter will be used to convert the file
    contents into an acceptable type. If the -r option is specified, a
    filter will not be used.

What I think this means is that -Tps will direct the request to a printer
that supports type ps (as you setup with 'lpadmin -I ps,simple'.  Since
you've declared that printer p4 accepts type ps it doesn't think it
needs to convert it.  The printer does not accept ps which is why you
need a filter invoked.


    o Setup a filter with input type ps and output type epson
    o Setup p4 to accept types epson and simple.
      This way it will accept the filter output or a normal unspecified input.

Now when you invoke lp with -Tps the system will determine that no
printers will accept type ps directly but there is a filter that will
convert from ps to a type supported by the printer and, hopefully,
invoke the filter.

You could just leave the filter output type as 'any' and leave the
printer input type as just simple (or unspecified) and it would still
work but creating a type specific to the type of printer the request
will only work if directed at the right kind of printer.  I.e. you would
want the request to fail if you did something like (lp -dlaserjet -Tps)
when your ps filter generates epson output.

In may case on unixware I setup two filters

filter lff:
    input=simple, output=lff, type=slow
    (This filter strips leading blank pages and trailing blank lines and pages)

filter laserauto:
    input=lff, output=fbpcl, type=slow, options='MODES auto = -auto'
    (This filter includes setup commands for a laserjet printer and
     optionally (-auto arg) sets font and orientation based on the
     longest line in the printout)

printer testpcl:
    lpadmin -ptestpcl -Ifbpcl

printer testtext:
    lpadmin -ptesttext -Ilff

So now if you do a simple print to testtext (lp -dtesttext) the default
input mode is simple but the printer only accepts type lff so the 
simile->lff filter is invoked.

If you print to testpcl (lp -dtestpcl) the printer only accepts type fbpcl.
There is no filter for simple->fbpcl but there are filters simple->lff and
lff->fbpcl.  The system figurs this out and strings the filters together.

The mode option to the laserauto filter is specified with -yauto on the
lp line (lp -dtestpcl -yauto).  If a filter supports the mode specified
in the -y arg (auto in this case) it passes the associated argument to
the filter program (as specified in the Options: line in the filter spec.
Do two rights make | Kevin Smith, ShadeTree Software, Philadelphia, PA, USA
a libertarian      | 001-215-487-3811  shady.com,kevin   bbs.cpcn.com,sysop
                   | dvtug.org,kevins--Deleware Valley Transit Users Group

Where do I find escapr codes for HP printers?s

Back before the dinosaurs died, printers came with manuals that had all this stuff in them. Nowadays, you are lucky if it's on the CD, and if it is, good luck finding it. Here's a few that may help for HPLaserjets:

Hexadecimal Code Decimal Code Octal Code Action
1B 11 27 17 033 021 Standard Tray
1B 15 27 21 033 025 (4050) Standard Tray
1B 14 27 20 033 024 MP Paper Tray
1B 15 27 21 033 025 500 Sheet Tray
1B 18 27 24 033 030 (4050) 500 Sheet Tray
1B 16 27 22 033 026 Optional Envelope Feeder

The octal codes are what you'd probably use in an interface script:

echo "\033\030\c"

Thanks to Jean-Pierre Radley and Richard Seeder

For a complete list of Laserjet codes see HP LaserJet Series Printers - PCL Commands, Basic Page Formatting, and Font Selection.

The ones to use for printing text:

echo "\033E\c" # Reset Printer
echo "\033&k2G\c" # Set line termination mode (LF=LF/CR).

Flush All complete pages \E&r0F 
Flush all page data \E&r1F

I don't find these two mentioned at that HP document.

They are referenced in this PCL 5 Technical reference PDF, which explains that these can be used to free printer memory but that they will reduce performance.

See PCL6 also.

Reform and other Form printing

You might find "Reform" printing scripts on Unix systems. I think that's this company now and I have no idea if they support those old products.

I found quite a bit from https://www.google.com searching for "linux forms printing". There was a lot of unrelated stuff, but I did find these, and I'm sure some of these should do it:

https://www.mpasystems.com.au/downloads/formsmaster/FormsMaster.PDF )
https://www.mpasystems.com.au/news/mpanews.htm (see Forms Master:
https://www.unibar.com/ (not really forms but might need it anyway?)

Keep in mind I didn't examine any of these very closely, so make sure you do..

Virtual port redirection

For some reaon, people wanted to be able to do things like "cat file > /dev/winbox/com1" and have the file spit out the serial port of a Windows machine. As printing to Windows printers is so easy, I never saw the point, but these things did exist and still do: Lantronix Com Port Redirector, for example.

Using SECSTOPIO for printer locking

SCO's SECSTOPIO kernel parameter controlled the behavior of the stopio(S) system call. This took a file path as an argument and, if set, would cause read, write and ioctl to fail - and also send a sighup to the process that dared touch its now protected file.

The SECSTOPIO parameter turns stopio on and off (0 or 1). Apparently some versions of SCO used this in printing and would send two SIGHUPS in quick succession and (because processes need some time to reset their traps) this would kill the offending process.

Use of stopio can be seen in places as unexpected as telnet locking its terminal - see telnetd stopio.

Using SECSTOPIO for printer locking

To restrict access, you can use /usr/lib/lpadmin -p printername -u deny:jim,fred,sam or (if it's easier) /usr/lib/lpadmin -p printername -u allow:root,tom,john

The same syntax will work for CUPS in Linux.

Or (for SCO) use "mkdev lp", select the printer, move to Settings->Advanced->Users and do it there, though that takes much longer..

For Linux, edit /etc/cups/printers.conf :

# deny everyone except these two
<Printer printername>
AllowUser tom
AllowUser john
# allow everyone except these three
<Printer otherprintername>
DenyUser tom
DenyUser john
DenyUser mary

For SCO, the allow and deny files are in /usr/spool/lp/admins/lp/printers. Each printer has a directory there, and you'll find the actual allow and deny files. Edit or remove them as appropriate.

Other stuff

Here's an odd one: UDP outbound to port 1230 every 17 seconds? - turned out to be an HP orinter broadcasting NTP requests!

Got something to add? Send me email.

(OLDER)    <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> Unix System V Printing


Inexpensive and informative Apple related e-books:

Take Control of High Sierra

Take Control of iCloud, Fifth Edition

Take Control of OS X Server

Take Control of Apple Mail, Third Edition

Are Your Bits Flipped?

More Articles by © Tony Lawrence

Sun Mar 15 13:55:24 2009: 5710   TonyLawrence

Loved this: (link)

Thu Dec 10 21:49:33 2009: 7733   anonymous

Hi, I need help with a serial printer in solaris 10.
The problem is: when a report finished, the other report not continued in the next page, i used /dev/term/a.
Please Help me !!

Thu Dec 10 22:11:40 2009: 7736   TonyLawrence

You need a form feed, obviously. Search here for "formfeed".

Tue Mar 23 15:23:52 2010: 8260   kris


i need your help, i have been searching on web but not able to get a clear answer. i have added a new network printer on unix server but when i try to send a print to the network printer, it prints some junk characters..i am not sure wt to do ..plz provide me step by step procedure to clear this issue.

Tue Mar 23 16:20:47 2010: 8261   TonyLawrence


Your question is far too vague and lacks detail. What kind of network printer? What OS? How did you configure it and how did you test it?

Sat Jul 30 17:39:43 2011: 9659   anonymous


hi, im working with SCO openserver 5 and i have 5 modules working, now i need to install a new printer and i went trough the installation on scoadmin, the system detected the printer and it was succesfuly added but i cant see the printers on the production modules. is there something im missing here ?

Sat Jul 30 17:58:12 2011: 9660   TonyLawrence


Can you print from the command line?

lp -d printername /etc/group

Wed Feb 29 20:12:57 2012: 10674   anonymous


We are trying to print a PDF and when I input lpadmin -p alkdf -0 length=80 etc, the printer will print from the correct tray BUT it will not print the file. If I go back and input the default values length= and width= it will print the file but the tray has to be manually selected. It's a Solaris 10 print server trying to print a PDF. Any ides?

Wed Feb 29 20:45:21 2012: 10675   TonyLawrence


Probably wrong driver but I haven't done any Solaris in many, many years, sorry.

Wed Apr 25 15:10:43 2012: 10887   bgibbs


I am still running a couple of legacy applications on an old SCO system, which has two Genicom line printers attached. One of the printers is starting to drop characters, so I'd rather avoid using it. Some of the application programs are hard coded to send print jobs (lp -dlpxx ...) to the bad printer. I know I can disable the bad printer and then manually move the print jobs (/usr/lib/lpmove...), but I'm looking for a way to automatically bounce any jobs sent to the bad printer over to the good printer. Is there a way to do this?

Wed Apr 25 15:14:49 2012: 10888   TonyLawrence


See "Wrapping one printer in another" above.

Tue Dec 18 20:25:07 2012: 11568   Chris


I have SCO Unix 5.0.7. I have setup remote printer and printers. Everything prints. I want to pass code to the remote printer. I'm using the HPLaserJet script. Where do I add the line "cat *$ |lp -dremoteprinter" in the script. Please advise or show sample. Thank you

Tue Dec 18 22:41:01 2012: 11569   TonyLawrence


I think you are confused about something. As phrased, your question makes no sense, sorry.

Thu Nov 6 22:18:41 2014: 12548   claudius


Making a network printer into a direct device-

For those that are so unfortunate that the neat named pipe trick does not work (as was for me, with a cobol program that was hanging on that), here is another way:

Create a regular empty file on /dev (or better a static link to it).
That would be your "device"
Make it rw - i.e chmod 666
then run a simple daemon script from /etc/rc, that every few seconds checks if the file is not any more empty, and , in such case prints it to the spooler, then sets its to zero again:

#! /bin/sh
while true
if [ -s /dev/fpr1 ] ;then
lp -dqpr1 /dev/fpr1
sleep 1
cp /dev/emptyfile /dev/fpr1
sleep 9

and inside /etc/rc:

/usr/local/bin/ckdaemon >/dev/null 2>&1 &

I have tested it and it works with SCO and 5.0.7 (Virtualized) also with remote ( rlp ) printers.

Long live Unix!


Printer Friendly Version

Have you tried Searching this site?

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.

Contact us

Printer Friendly Version

Anyone who slaps a 'this page is best viewed with Browser X' label on a Web page appears to be yearning for the bad old days, before the Web, when you had very little chance of reading a document written on another computer, another word processor, or another network. (Tim Berners-Lee)

Linux posts

Troubleshooting posts

This post tagged:



Unix/Linux Consultants

Skills Tests

Unix/Linux Book Reviews

My Unix/Linux Troubleshooting Book

This site runs on Linode