Linux System Administration: A User's Guide Part 2 of 3

Linux System Administration: A User's Guide Part 2 of 3

This is an excerpt from Chapter 13 of Linux System Administration: A User's Guide written by Marcel Gagne, published by Addison-Wesley. ISBN 0201719347. No part of this excerpt may be reproduced, in any form or by any means without the prior written permission of the publisher. (c) 2002 Addison-Wesley

Printing Anything to Any Printer
I'd like to talk a little bit more about filters. In my office I have a small HP LaserJet 5L. It's the one I've been using for all the examples in this chapter. If you've spent any time whatsoever with Linux (or other UNICes/UNIXes), you know that most applications print using the PostScript format. Unfortunately, my printer doesn't print PostScript. Luckily, Linux is distributed with a little package called ghostscript.

I won't spend much time on ghostscript except to tell you that it's a powerful tool that also makes a great print filter. If I try to print a PostScript file to my printer, it comes out as strange text, which just happens to be a kind of code - code written in the PostScript language. Looking at the first 10 lines of a PostScript file on my system, I see this:

# head
%%BoundingBox: 54 72 558 720
%%Creator: Mozilla (NetScape) HTML->PS
%%DocumentData: Clean7Bit
%%Orientation: Portrait
%%Pages: 1
%%PageOrder: Ascend
%%Title: Registrant Name Change Agreement

This is also what it looks like if I just send it to my printer without a filter of some kind that can interpret PostScript. Different Linux distributions offer different alternative filters, but all should have ghostscript in common.

Here's an example: I'll send my file to the printer but pass it through a ghostscript filter beforehand. (Note that the following line wraps. It's just one line.)

# cat | gs -q -dNOPAUSE -sDEVICE=ljet4 -r300
-sPAPERSIZE=letter -sOutputFile=- - | lpr

I know it looks like a lot to take in, but it's pretty simple. The -q means that ghostscript should perform its work quietly. Normally, ghostscript would put out a lot of "this is what I am currently doing" information, not what I want for a print job. The-dNOPAUSE tells ghostscript to process all pages without pausing to ask for directions. The first -s flag that you see specifies the printer type. The ljet4 definition covers a whole range of LaserJet printers that can do 600 dpi resolution.

This brings me to the -r flag, where I define a 300 dpi resolution. This Netscape Navigator-generated page (remember, you can print to a file when using Netscape Navigator) doesn't need a 600 dpi resolution. ghostscript also enables me to specify paper size, important for those of us in North America who hold firmly (if not wisely) to the 81/2x11-inch letter-size format. Finally, I specify standard out as my output file. Notice the last hyphen in that line. It means that ghostscript is taking the input through its standard in. The last thing I do is fire it to the printer.

The great thing about ghostscript is its extensive printer support. Visit the ghostscript printer support page ( to see the latest and greatest list of support. When you visit the site, scroll down the list and click the "printer compatibility" link.

Armed with this, I could use essentially the same line to create an output filter for printing. Remember the dosfilter example earlier? There was only one real active line in the filter script (other than the staircase effect change) and that was a simple cat. That line would now be the ghostscript line from the previous code minus the | lpr at the end of it.

gs -q -dNOPAUSE -sDEVICE=ljet4 -r300 -sPAPERSIZE=letter -sOutputFile=- -

You can even use ghostscript as a desktop X viewer for PostScript files and documents by simply typing gv followed by the name of the file you want to see. gv, as you might have guessed, stands for "ghostscript viewer" (see Figure 1).


Tying It Up: Advanced Filters with Ghostscript
All right, let's put some of the ideas from Parts 1 and 2 together. As I mentioned, a number of programs generate PostScript only rather than trying to create output for different printer types and languages. In the Linux world, that accounts for a lot of programs. Netscape Navigator is one such program, as is StarOffice from Sun Microsystems. So how do you deal with this?

Let's start with a quick reminder of the ghostscript output filter to convert PostScript to my LaserJet 5L printer. I've saved this file as /usr/local/ bin/psfilter and made it executable with chmod 755 /usr/local/ bin/psfilter.

# Ghostscript filter so that my HP LJ5 will print PostScript files
echo -ne \\033\&k2G
gs -q -dNOPAUSE -sDEVICE=ljet4 -r300 -sPAPERSIZE=letter
-sOutputFile=- -

Now I also have a definition for the printer that uses that output filter.


Why PostScript?
The simple answer is that PostScript is close to a standard for defining objects (whether text or graphics) to printers, plotters, and even video screens. PostScript was designed to be completely device independent. Consequently, it provides a virtually universal print file format. PostScript (a trademark of Adobe Systems) was developed in the mid-'80s and is actually a programming language. Because PostScript files are plain text, you can use a text editor to modify the source - even that of an image.

PostScript has been used in the UNIX world for many, many years. Because a number of the programs that come with your Linux system were originally designed in the UNIX world, it's not surprising that they work with PostScript. This is a plus, not a minus. As a result, you'll find many great tools specifically for working with PostScript. Furthermore, because you can print any PostScript file to any printer, everyone can do this.

A Few PostScript Tricks
Say you've got a two-page document (a program listing or a collection of bad, but funny, one-liners) and you want it to take up only one page (they're not that good). That's where the mpage command comes into play. You're now going to print this document so that two pages fit onto one. The output will be rotated, so this will actually come out as portrait orientation.

mpage -2 funnyjokes.txt | lpr -Ppshpljet

The two pages appear on one page with a nice thin line around both pages. Let's make this just a little fancier, shall we? Try out the next command and see what kind of output it generates.

mpage -2 -B-5r-5l-3t-3b3 -M50l50r50t50b -H prog_specs.txt | lpr -Plptest

What does this all mean? The -2, by the way, could be a -4 to fit four logical pages per physical page. Just so you're clear on my hastily chosen terminology, I'm using the terms logical and physical to differentiate the printer output from the physical, "hold it in your hand" page. You can even do a -8, but that might be getting a tad silly. The -B-5r-5l-3t-3b3 part means that a bold line (3 point) should be drawn around the box. That's actually the last 3 at the end of that line. The -5r-5l-3t-3b part means that you want a three-line margin at the top and bottom and a five-character margin at the left and right. The -M line uses a similar format and gives you a 50-point margin all around your virtual page. Remember that you have two logical pages on one physical page in this example. Finally, -H means you want a header on each page. The header has the date on the right, the filename in the center, and a page number on the right.

Where would you use this? One place that comes immediately to mind (after the one-liners, that is) is source code for your programs. This is a great way to generate compact program listings without having to import them into a word processor. I should point out that there is a non-PostScript way to create simple, numbered pages. All you have to do is use the pr command. Try this with a text-only printer definition:

pr +2 -h "Secret Kernel Enhancements" -o 5 ftl_travel.c | lpr -Ptextonly

pr is a command designed to format text for printing. The preceding line says to take the file ftl_travel.c, start printing at page 2 (+2), add a left-hand indent of 5 spaces (-o 5), and print the header "Secret Kernel Enhancements" on each page (-h followed by a string). If you do not specify a different header name, you'll get the filename itself, in this case ftl_travel.c. Oh, yes…it will actually start numbering the pages at page 2.

End Part 2

More Stories By Maureen O'Gara

Maureen O'Gara the most read technology reporter for the past 20 years, is the Cloud Computing and Virtualization News Desk editor of SYS-CON Media. She is the publisher of famous "Billygrams" and the editor-in-chief of "Client/Server News" for more than a decade. One of the most respected technology reporters in the business, Maureen can be reached by email at maureen(at) or paperboy(at), and by phone at 516 759-7025. Twitter: @MaureenOGara

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.