I've used a script called lpr2, it does what you want
#!/bin/sh
# LPR2 -- Utility to print postscript document on both sides.
# Version 1.2d
# Copyright (c) 1994 Frangois-Reni "Fari" Bbn Rideau DDa(.ng-Vu~
# (rideau@ens.fr,rideau@frmap711.mathp7.jussieu.fr)
# COPYRIGHT NOTICE:
# This program is distributed under the terms of the GNU General Public
# License (any official version you can find). There is absolutely NO WARRANTY
# about what effect it can have on your software or hardware.
# You may strip off this file any comment or unuseful characters and
# statements, but only for personal use. A distributed copy of this software
# must include it all. You should also feed back any modification done to this
# program. Any feedback is welcome whatever (see below).
# WHAT IT IS MEANT TO DO:
# To save paper, and lighten you backpack, without lightening your purse by
# buying printers that already print documents on both sides, do use this
# program to print double sided documents.
# Not throwing away paper is good for just everyone throughout the world.
# Stop the spillage, help save the world, use LPR2 !
# The latest version should be available by anonymous ftp.
# Try ftp://sunsite.unc.edu/pub/Linux/system/Printing/lpr2*
# Enhanced version 1.2 now works with *all* documents I've tried it with !!!
# WHAT IT IS *NOT* MEANT TO DO:
# This program is NOT a "standalone" postscript interpreter. You still need
# another PostScript interpreter to get it to work. The interpreter can be
# just your PostScript printer, or GhostScript, or whatever.
# If you have a non-PostScript printer, the Printing-HOWTO (also somewhere
# on sunsite) will explain you how to set up "lpr" to work with PostScript
# documents anyway, using GhostScript as the interpreter.
# HOW IT WORKS:
# The shell part is only a wrapper to accept all the different options.
# The core of the program (the shell function redefshowpage) prepends some
# PostScript code to the file to print, that redefines "showpage" so that it
# will print every other page. According to the new showpage skipping the
# first page or not, we obtain one document for recto sides, and one another
# for verso sides. We then have to print it all...
# Note that as the program redefines *global* variables, it cannot be
# recursively called. But as the page selection function is programmable,
# such use isn't needed. If you know how to reliably use local variables
# in postscript, please tell me.
# There should not be any clash with variables from the postscript file to
# be printed; if however there was one, you can still modify those names in
# the postscript part of lpr2.
# INSTALLATION PROCEDURE:
# - gunzip lpr2
# - chmod 0755 lpr2
# - mv lpr2 /somewhere_in_my_path/bin/
# - edit the file to customize if need be (look for !!!! marks):
# the LPR= line should contain the name of a command or function that
# will print its PostScript standard input. I put "lpr" as the default.
# Enjoy !
# USAGE:
# To print document "doc.ps", print odd pages on one side and even pages on
# the other.
#
# My HP LaserJet 4ML printer issues pages in the "right" order, i.e. the
# page on top exits on top. I also have to feed paper with verso (back) upward,
# and top of sheet near me. Thus, I have to print even pages first, then odd
# pages. That's what the default behaviour is.
#
# Rainer Blome (rainer@physik3.gwdg.de) says:
# My default `PostScript' printer, an HP LJ III, does emit pages in the
# `right' order (small page numbers on top), but does not feed verso. a
# stack of paper exits the printer exactly the same configuration as it has
# been put in the paper cassette.
# To get the desired result, however, i need the pages in this order, yes,
# but the empty side has to be in the position that will be printed on. the
# HP IV does that automatically, each page is reversed on every printing.
# Thus, `print on reverse side' with `emit in right order' is OK, as is
# `print on topside' with `emit in wrong order'. other combinations require
# reordering/reversal by hand.
#
# If you need some other behaviour, please tell me or correct it and send
# me feedback.
#
# Beware that there may be one odd page more than even pages. Sheets must be
# fed with verso on top. Default option (--all) does it.
#
# Thus, the usage is: feed blank sheets to the printer, mark one corner with
# a pencil to see how you will have to feed sheets again to print the other
# side. Then, print even pages. Insert printed pages back into the printer
# in the right order and side, as determined by the pencil, and
# print odd pages.
# INVOCATION: lpr2 [options] files
#
# option what it means
# -1,-o,--odd "print only odd pages"
# -2,-e,--even "print only even pages"
# -c,--cond "the string just after this is the postscript condition for
# a page to be printed, e.g. '4 eq'"
# -s,--select "print only the page whose number follows '-s' "
# -a,--all "print even pages; prompt; print odd pages" (default)
# -N,--noprint "do not send to printer, but to standard output"
# -r,--reverse "print odd pages; prompt; print even pages in reverse
# order" (beware: remove last sheet if odd number of pages)
# NOT IMPLEMENTED YET, and not to be soon, as it involves much
# more than just a postscript header. Use mpage or psrev (from
# the psutil package) if you need such thing. Unhappily, those
# packages are far less reliable than lpr2 v1.2
# THE AUTHOR:
# I'm no PostScript guru *at all*. It's my first (and perhaps last)
# PostScript program. I've never read any Postscript book or official
# documentation or programming recommendation; only gs manpage and
# examples. Postscript looks like a great language to me; very FORTH-like
# indeed.
# I developped this program under Linux using Ghostscript 2.6.1 in five
# minutes. I'm actually spending more time documenting it and transforming
# it into a shell utility than I did writing the postscript stuff.
# HOW WELL THE PROGRAM SHOULD BEHAVE:
# This program works very well for me.
# - you need a shell that supports shell functions (SYSV or SunOS shells do,
# while Ultrix shell doesn't). If yours doesn't work, try getting ksh, bash or
# better even, zsh on the net.
# - The program should work on any well-behaved PostScript document (i.e. the
# kind of documents standard applications produce), but is reported to fail
# when used in combination with some dirty Postscript utilities. mpage by
# Mark P. Hahn 1988 is such dirty program that fails :( :(. Happily, newer
# versions already support page selection.
# - You should be able to refeed the printer with its first output, and of
# course, be sure that no one else will use the printer while you are feeding
# the printer with the output for the verso side of the documents.
# - If your printer output pages in the reverse order, you're in for a double
# session of reordering pages :( :( :(
# HISTORY:
# version 0.0: just postcript code manually prepended to a document.
# developped with ghostscript.
# version 0.1: the same, but it works (with the discovery of erasepage)
# version 1.0: a script that doesn't even work (I'm ashamed of that)-8
# version 1.1: the same, but bugs fixed:
# - cat <<"END" was used instead of cat<<END,
# and did not expand $1.
# - %! was forgotten on the first line of the document,
# which can make auto-detection of file format fail for lpr2
# documents.
# - "echo lpr" was also done instead of lpr :(
# And a new feature added:
# - if "-" or no file is given, lpr2 will work even with option
# "--all", by saving input in a file to reread it the second
# time. Exit and signals are trapped to rm it.
# version 1.1b: Help was increased thanks to the kind feedback of
# Warwick Hockley <hock@adhoc.apana.org.au>.
# Help options are supported.
# version 1.1c: bugs corrected: quotes not closed >8 ; run-time message
# modified
# version 1.1d: added arbitrary page selection
# version 1.2: used the ps2ppm PageCount trick using strings to escape
# save/restore sequences. lpr2 now works with all files
# I've tried it with !
# version 1.2b: Just understood why ps2ppm added 1000000 to page count.
# lpr2 now works after page 9 :)
# version 1.2c: added nicer page selection: page can be named as p...
# version 1.2d: merged feedback from Rainer Blome (rainer@physik3.gwgd.de):
# - removed the -P,--print "I changed my mind. Do print" option
# - extended the description of how to reinsert paper.
# TO DO
# - add support for options that'd select multiple pages.
# - if the last page to be printed is known, put some "end execution"
# PostScript order in the test condition of the program...
# - first find how this can in done in PostScript :)
# FEEDBACK: TELL ME ABOUT YOUR USING THIS PROGRAM.
# If you like it, send me a postcard, or even just an e-mail. If you have
# money to give away, give it to a beggar just round the corner. If it's too
# much money for you to give him, send it to any charitable or ecologic
# association.
# Any (positive or negative) feedback is welcome. Send me your appreciations,
# your diffs, your improvements. Or just say "hello".
# Feed back should be sent to one of my addresses below:
# AUTHOR'S .SIGNATURE AND ADDRESSES:
#- , , _ v ~ ^ --
#- Fare -- rideau@clipper.ens.fr -- Francois-Rene Rideau -- +)ang-Vu Ban --
#- ' / . --
#MOOSE project member. OSL developer. | | /
#Dreams about The Universal (Distributed) Database. --- --- //
#Snail mail: 6, rue Augustin Thierry 75019 PARIS FRANCE /|\ /|\ //
#Phone: 033 1 42026735 /|\ /|\ /
########################## The Postscript stuff ##############################
redefshowpage ()
{
# have as argument condition on page to show
cat <<-END
%!PS-Adobe-3.0
/.show.this.page.p { $1 } def
/.page.number 1000001 7 string cvs def
/.showpage.orig /showpage load def
/.erasepage /erasepage load def
/.showpage.lpr2 {
2 dict begin
/p .page.number dup cvi dup 1 add 3 2 roll cvs pop 1000000 sub def
mark p
% (lpr2: showpage called for page ) print dup =only (.\n) print flush
.show.this.page.p
/c exch def cleartomark c
end
{ % (lpr2: showing page.\n) print flush
.showpage.orig }
{ % (lpr2: skipping page.\n) print flush
.erasepage }
ifelse
% (lpr2: showpage ended.\n) print flush
} def
%Redefine showpage...
/showpage { .showpage.lpr2 } def
END
}
########################## The shell functions ##############################
doprinteven ()
{
(redefshowpage "2 mod 0 eq" ; cat $FILES) | $SENDJOB
}
doprintodd ()
{
(redefshowpage "2 mod 1 eq" ; cat $FILES) | $SENDJOB
}
doprintcond ()
{
(redefshowpage "$COND" ; cat $FILES) | $SENDJOB
}
prompt ()
{
echo "$@" > /dev/tty
read dummy_answer < /dev/tty
}
doall ()
{
prompt '
Feed the printer with blank sheets.
If you don'"'"'t how to feed the printer again to achieve printing on
the "right" side, mark corners of the first sheets with a pencil.
When you'"'"'re done, press "Enter".
'
doprinteven
prompt '
First, do wait for the thing to have been printed.
Now, if your printer issues pages in the wrong order, you have a problem.
You'"'"'ll have to reorder everything twice. Next time, try --reverse option
if it'"'"'s implemented.
The first thing to do after having recovered the back sides of your printed
documents is to ensure that no one else will use the printer while you'"'"'re
printing on the other side.
When this is done, feed the printer back with the same sheets, but
place the sheets so that the other side will be printed (with the same top
of page). If your document has an odd number of page, add a blank sheet at
the end.
When you'"'"'re done, press "Enter".
'
doprintodd
}
doreverse ()
{
echo "NOT IMPLEMENTED YET" > /dev/tty
}
calllpr ()
{
$LPR $LPROPTS
}
cleanexit () {
$RM $FILE
exit 1
}
######################### The command line interface ########################
LPR=lpr # !!!! replace with your standard printing command
# may be just "cat > /dev/lp1". lpr should be fine.
RM=rm # !!!! replace with your standard file deletion command
# may be "/bin/rm -f -", but rm should be fine.
# These should be ok and not need any modification
TODO=doall
LPROPTS=
FILES=
SENDJOB=calllpr
ParseOpts () {
while [ -n "$*" ] ; do
i="$1" ; shift
case "$i" in
-a|--all) TODO=doall ; SENDJOB=calllpr ;;
-r|--reverse) TODO=doreverse ; SENDJOB=calllpr ;;
-N|--noprint) SENDJOB=cat ;;
# -P|--print) SENDJOB=calllpr ;;
-1|-o|--odd) TODO=doprintodd ;;
-2|-e|--even) TODO=doprinteven ;;
-c|--cond) TODO=doprintcond ; COND="$1" ; shift ;;
-s|--select) TODO=doprintcond ; COND="$1 eq" ; shift ;;
-h|-?|--help) echo "use \`\`more $0'' for help about this program" ;
exit 0 ;;
-v) echo "LPR2 v1.2d" ; exit 0 ;;
--version) echo "LPR2 -- version 1.2d" ;;
-*) LPROPTS="$LPROPTS $i" ;;
*) FILES="$FILES $i" ;;
esac
done
}
DoIt () {
: '":" is for debugging'
: LPR=$LPR
: TODO=$TODO
: SENDJOB=$SENJOB
: LPROPTS=$LPROPTS
: FILES=$FILES
case "$SENDJOB$TODO$FILES" in
catdoall*|catdoreverse*)
echo "Incompatible options" ;
exit 1 ;;
calllprdoall*" - "*|calllprdoreverse*" - "*|calllprdoall|calllprdoreverse)
FILE=/tmp/lpr2-$$
trap cleanexit EXIT HUP TERM
cat > $FILE
FILES=$FILE $FILES
$TODO
;;
*) $TODO
;;
esac
}
ParseOpts "$@"
DoIt
---------------------------------------------------------------------------
BogoMIPS Research Labs -- bogosity research & simulation -- VE7JPM --
jmorriso@bogomips.com ve7jpm@ve7jpm.ampr.org jmorriso@ve7ubc.ampr.org
---------------------------------------------------------------------------