[Printer] みんなでプリンタを使おう (BSD編)

プリンタの設定と共有について、情報を集めています。特にUNIXワークステーションにプリンタをつなぎ、それをUNIX環境から、あるいはPCから利用する方法が中心です。

lbp-ifのウェブサイト移転に対応(2011-12-07)

このページではBSD系UNIXの印刷スプーラLPDを扱っています。実際にはSunOS 4.1.xでの設定例が中心です。Solaris 2.xなどSVR4系のOS でプリンタを接続して利用する方法は、「みんなでプリンタを使おう (Solaris編)」を御覧下さい。また、ネットワークプリンタを利用する方法は、長くなったので独立したページに引っ越しました。

[go!] みんなでプリンタを使おう (Solaris編)
[go!] ネットワークプリンタを使う

日経BP, Find'X(コンピュータ・通信分野の専門検索サイト)に「厳選お薦めサイト」として登録されました。

あなたはだいたい ???人目のお客様です。(1997年3月1日以降)


* プリンタの接続形態による分類

おいおい説明しますが、たいていのプリンタは印刷したいファイルをただ流し込んだだけでは印刷できず、そのプリンタに合わせた変換が必要となります。どうやって変換するかも重要ですが、その前に、その変換をどのマシンで行なうかを決めなければなりません。

あるマシンからプリンタを使おうとするとき、そのマシンから見た対象のプリンタの接続形態によって、次のようにプリンタを分類することができます。

ローカルプリンタ
当該マシン(UNIXワークステーション)に直結されているプリンタ。た いていの場合は、シリアルポートまたはパラレルポートを介して接続 されます。この場合は他のマシンの助けを借りることはできないので、 印刷の設定や印刷データをプリンタ記述言語に変換する作業は、自前 で行なわなければなりません。
リモートプリンタ
他のマシン(UNIXワークステーション)を経由して印刷するプリンタ。 あるマシンに取っては"ローカルプリンタ"に見えるものは、別のプリ ンタからはリモートプリンタとして利用できます。
この設定がもっとも簡単です。印刷データを変換する作業は、プリン タがつながっているマシン(印刷サーバ)が行なうので、ただデータを 転送するだけで済みます。
ネットワークプリンタ
Ethernetインターフェイスなどを持っていて、どのマシンにも直結さ れずに、ネットワークに接続して利用するプリンタをこう呼ぶことに します。印刷データを自前で変換しなければなりません。

対象のプリンタがネットワークプリンタであっても、印刷は別のマシン(印刷サーバ)を経由して行なうときには、リモートプリンタとして設定します。

このページではまずローカルプリンタの接続と設定について扱い、次にネットワークプリンタの設定について書きます。リモートプリンタの設定方法については述べていません。悪しからず。リモートプリンタは、マニュアルや参考文献をちょっと調べればすぐに設定できますから頑張ってね。


* Sun SPARCstationのパラレルポートとケーブル

-> パラレルポート接続の注意点とテスト方法


* BSD系OSでのプリンタの設定

BSD系の印刷スプーラLPDで、プリンタをなるべく利用しやすいように設定する方法を説明します。目標は、

  1. lprコマンドで印刷できる。
  2. 漢字の入った文書も印刷できる。
  3. 非PostScriptプリンタであっても、PostScriptファイルを印刷できる。
  4. テキストファイルとPSファイルの違いを意識せずに印刷できる。ファ イルの種類の識別は利用者ではなく印刷スプーラが行う。
  5. プリンタの制御コード(ESC/PやLIPS IIなど)で書かれたファイルをプ リンタに流し込むことができる。(lprに"-l"オプションをつける。)

といったところです。これら全てを実現するのは、結構大変なんですよ。UNIX の解説書を読んだだけではできないはずです。

この節では、lprコマンドを使ってテキストファイルが印刷できるところまでを簡単に説明します。

LPDは、BSD系のOSで採用されています。SunOS 4.xは厳密に言えばBSD系の OSではありませんが、印刷スプーラはLPDを使います。 Solaris 2.xなどSVR4系のOSでプリンタを接続する方法は、 「みんなでプリンタを使おう (Solaris編)」を御覧下さい。

* フィルタを用意する

たいていのプリンタは、テキストファイルをそのまま流し込んでも意図した通りの印刷結果が得られません。これはなぜかというと、

などの理由が考えられます。

この障害を乗り越えてテキストファイルを印刷できるようにするためには、 フィルタと呼ばれるコード変換ソフトウェアを用意する必要があります。フィルタは例えばテキストファイルをプリンタが理解できるコードに変換する、などの仕事を行います(もっといろいろな仕事をさせることも出来ます)。このフィルタさえ用意できれば、半分勝ったようなものです。

テキストファイルを扱うフィルタには、例えば次のようなものがあります。 (すべて私の所属する流体研で実際に使われている/使われていたものです。)

lbp-ifおよびesc-ifについては、以下のページをご覧下さい。

-> lbp-ifとesc-ifのページ
(作者である伊藤 高一氏による)

lbp-ifとesc-ifは、どちらも利用制限があります。ご利用になる前に、必ず付属の文書をお読み下さい。

LIPSに関しては、大森 紀人氏のページも参考になります。特にLIPS III以上に対応した新しいプリンタをお持ちの場合は、それに対応したフィルタを用いた方が、LIPS II+用のフィルタを使うよりもきれいな出力を得られるので、検討する価値があります。

* 印刷スプーラの設定

以下の説明では、例としてCanon LBP-B406というページプリンタを取り上げます。古い…。私の所属する流体研では、裏紙専用のプリンタとして活躍しています。 (ほぼ同じ設定で、Canon LBP-720というページプリンタも使っています。)

Canon LBP-B406はLIPS IIを受け付けますので、フィルタにはlbp-ifを使うことにします。

BSD系の印刷スプーラ(LPD)は/etc/printcapというファイルをいじってプリンタの設定を行います。例えば次のような内容をprintcapに追加します。

# Canon LASER SHOT B406 (Good Old Monocrome Laser Printer)
# on /dev/bpp0 (parallel port)
lbp-b406|lbp|lips2|Canon LASER SHOT B406 (LIPS II):@BACKSLASH@
	:lp=/dev/bpp0:@BACKSLASH@
	:sd=/usr/spool/lpd/lbp-b406:@BACKSLASH@
	:lf=/usr/adm/lpd-errs:@BACKSLASH@
	:af=/usr/spool/lbp-b406/log:@BACKSLASH@
	:if=/usr/local/lib/lp/lbp-if:@BACKSLASH@
	:mx#0:@BACKSLASH@
	:sh:@BACKSLASH@
	:rw:

# ではじまる行はコメント行です。そのすぐ下の1行が、プリンタの名前を決めているところです。lbp-b406、lbp、lips2など複数の名前を登録しています。 このプリンタを標準のプリンタとして使うのでしたら、lpという名前も追加して下さい。"lp"という名前のプリンタが、lprコマンド等をプリンタ名を省略して使った場合の、標準プリンタとして使われるからです。

lp=/dev/bpp0という行は、プリンタが接続されているデバイスを指定します。/dev/bpp0というのはSun SPARCstationのパラレルポートを指します。マシンの機種やOSが異なるときは、この名前も異なります。また同じSunOSを使っていても、シリアルポートにプリンタを繋いでいるときには異なる設定をする必要があります。(ここではシリアル接続の説明はしませんので御了承下さい。)

sd=/usr/spool/lpd/lbp-b406という行は、印刷するファイルを一時的に溜めておくディレクトリ(スプールディレクトリ)を指定しています。ディレクトリ構成はOSによって異なるので気をつけて下さい。

lf=/usr/adm/lpd-errsという行は、印刷時のエラーなどのログを取るためのファイルを指定しています。 af=/usr/spool/lbp-b406/logという行は、アカウンティングのためのログ、つまり誰がどれだけ印刷したかを記録するためのファイルを指定しています。

その次の、if=/usr/local/lib/lp/lbp-ifという行が、フィルタを指定するための行です。フィルタを置いたパスに合わせて書き換えて下さい。

最後の3行については説明を省略します。printcapの書き方は書籍や雑誌などで詳しく解説されていますので、詳しくはそちらを御覧下さい。

* 印刷テスト

さて、ちゃんと印刷できるでしょうか、試してみましょう。適当なテキストファイルを用意して、

lpr -P printername  filename

と打って下さい。うまく印刷できたらやれやれです。

* 付記

lbp-if、esc-ifはすでにプリンタ用のコードに変換されているファイルを印刷することもできます。つまりファイルを変換せずにそのままプリンタに送るわけです。

lpr -l filename

のようにオプションをつけて印刷して下さい。

-> プリンタ制御コードを含むファイルを印刷できるようにする理由


* 非PostScriptプリンタをPostScriptプリンタとして使う

PostScriptインタプリタGhostscriptを用いて、非PSプリンタをPSプリンタに仕立てる方法を説明します。やり方はいろいろあるのですが、テキストファイルもPostScriptファイルも印刷できるように 印刷スプーラ側でファイルの分類をする方法を紹介します。

* Ghostscript

GhostscriptはAlladin Enterprisesが開発・保守を行っているソフトウェアで、フリーソフトウェアとして配布されています。このソフトウェアの機能は以下の通り。

[go!] Ghostscriptの使い方いろいろ

すでにGhostscriptがインストールされていてそれを使おうと思っていらっしゃる方は、まずはじめに出力したいプリンタの制御コードを扱うドライバが、お手元のGhostscriptに組み込まれていることを確認して下さい。確認には gs -hというコマンドを打ち込んでその出力をじっと見て下さい。 Ghostscriptをコンパイルするときに必要なドライバを組み込んでおかなかったのであれば、再コンパイルが必要になります。

* PostScript用のフィルタを用意する

前節はテキストファイルをプリンタの制御コードに変換するフィルタを紹介したのですが、今度はPostScriptファイルをプリンタの制御コードに変換するフィルタが必要です。さてPostScriptファイルを操作する、となると Ghostscriptの出番です。

例として再びCanon LBP-B406を取り上げます。LIPS IIのドライバは最新の Ghostscriptには含まれていないので、私はGhostscript-2.6.2の日本語化パッチに含まれているドライバを利用しています。

実際に私が使っている、Ghostscriptを利用したLIPS II用のフィルタを紹介します。シェルスクリプトになっています。

#!/bin/sh

# lbp-b406-if-ps: Canon LBP-B406用PostScriptフィルタ
# PostScriptファイル --------> イメージビットマップ
#			GS
#		-------------> パラレルポート /dev/bpp0	
IFS=""; export IFS
PATH="/usr/bin"; export PATH


# 一時ファイル
TMPDIR=/tmp
OF=$TMPDIR/lbp.$$.code
DEV=lips
# DEVOPT=""


# gsコマンドの絶対パス
gs=/usr/local/bin/gs262

width= length= indent= user= host= afile=


# 引数処理
while test $# != 0
do case $1 in
	-c) ;;
	-x*)    width=$1 ;;
	-y*)    length=$1 ;;
	-n)     user=$2 ; shift ;;
	-n*)    user=`expr $1 : '-.\(.*\)'` ;;
	-h)     host=$2 ; shift ;;
	-h*)    host=`expr $1 : '-.\(.*\)'` ;;
	-*)     ;; 
	*)      afile=$1 ;;
esac
shift
done


# SIGINTが発行されたときの後始末
trap '/bin/rm -f $OF;
	echo "$user@$host job LBP-B406 is terminated at `date`" 1>&2;
	exit 2' 2


# ここからが主処理部分
$gs -q -dSAFER -dNOPAUSE -sDEVICE=$DEV $DEVOPT -sOutputFile=$OF @BACKSLASH@
        - -c quit 2>&1 >/dev/null || exit 2

cat $OF || exit 2
rm -f $OF

if [ x$afile != x ]; then
	echo "$user@$host printed PostScript file at `date`" >>$afile
fi

exit 0
# eof

「引数処理」の部分は、よく分からなければ無視して下さい。実際の変換を行っているのは後半のところです。

ここは大切!
さて出来上がったこのフィルタをprintcapにそのまま登録してもよいのでしょうか。もしこのまま登録すると、PSファイルは印刷できるようになりますが、テキストファイルはそのままでは印刷できなくなってしまいます(!)。上記のシェルスクリプトはPSファイルの印刷しか想定していないからですが、これでは不便ですね。そこで、ここを何とかする方法を次に説明します。

* ファイルの種類を識別するプログラムlprps

printcapに上記のフィルタを直接登録するかわりに、印刷するファイルの中身を解析してその種類を識別し、適切なフィルタを起動してくれるようなプログラムを登録して使うことにしましょう。こういう目的には、 lprpsというプログラムがあります。

[Down] lprps-2.5.tar.gz (tar+gzip、約32kB)

lprpsのパッケージには、印刷するファイルを解析してテキストファイルとPS ファイルの識別をするpsifというプログラムが入っています。私はこれを改造して使っています。改変したのは以下の2点です。

以上の変更を施すためのパッチを用意しました。お役に立てば幸いです。

-> プリンタ制御コードを含むファイルを印刷できるようにする理由
[Down] psif.c.diff

フィルタを置くディレクトリはソースコードに直接書き込まれています。適当に書き換えてご利用下さい。

* psif利用の具体例

Canon LBP-B406の場合を例に取って、使い方を具体的に説明します。まず、フィルタを次のような名前でコピーします。

/usr/local/lib/lp/lbp-b406-if
上記psifのコピー
/usr/local/lib/lp/lbp-b406-if-text
テキストファイル用フィルタ、lbp-ifのコピー
/usr/local/lib/lp/lbp-b406-if-ps
PSファイル用フィルタ、上で説明したシェルスクリプト

次に/etc/printcapを編集し、フィルタをlbp-b406-ifに設定します。つまりif=/usr/local/lib/lp/lbp-b406-ifとします。

これでおしまいです。テキストファイルおよびプリンタの制御コードを含むファイルはテキストファイル用のフィルタを通って、PSファイルはPSファイル用のフィルタを通って印刷されるはずです。

* プリンタ制御コードを含むファイルを印刷できるようにする理由

プリンタ制御コードを含むファイルを印刷できるようにしておく理由は何でしょうか。事情はいろいろあるでしょうが、私にとって重要な理由は次のようなものです。


* ふつうのPostScriptプリンタの場合

上記の方法をそのまま普通のPSプリンタに応用するのはお勧めできません。なぜなら上記のpsifを使う方法では、

のように仕事を振り分けています。しかしPSプリンタの場合はプリンタ制御コードがすなわちPostScriptですから、

のように振り分けたい。この場合は次のような方法が考えられます。

  1. パッチを当てていないpsifを使う。これだとバイナリファイルをはじ く機能が働くので、PSプリンタには都合がよいでしょう。
  2. プリンタ制御コードが来たとき、つまりフィルタに"-c"オプションが 付けられたときだけ処理を変えるようなフィルタを書く。

1番目の方法のほうがよいとは思いますが、2種類のフィルタを使い分けるのが面倒なので、私は2番目の方法を採っています。具体的には次のような簡単なシェルスクリプトをテキストファイル用のフィルタとして登録しています。

#! /bin/sh

# qms1660-if-text --- テキストファイルをPostScriptファイルに変換する。
# 漢字コードの変換も行う。
PSfilter=/usr/local/lib/lp/qms1660-if-ps

for arg in $*; do
  if [ $arg = "-c" ]; then
    imageflag="-c"
  fi
done

if [ -z "$imageflag" ]; then

  # テキストファイルだと判断して、漢字コードを変換し、
  # PSファイルに変換する。
  /usr/local/bin/nkf -e | /usr/bin/jtops -v | $PSfilter "$@"
else

  # 生データ(=PSファイル)として扱う。
  exec $PSfilter "$@"
  # NOTREACHED
fi

exit 0
# eof

このシェルスクリプトははQMS 1660というPS互換プリンタ用のフィルタです。 QMSはテキストファイルをそのまま送っても印刷してくれるのですが、漢字コードを含む文書は印刷してくれないので、上記のフィルタを噛ませています。


* ネットワークプリンタを使う

この節は長くなり過ぎたので、独立したページに引っ越しました。以下のリンクをたどって下さい。

[go!] ネットワークプリンタを使う


* プリンタ雑学

すんません、ホントにつまらん情報しか置いて無いっす。出来ることならだんだん充実させていこうと思います。

* パラレルポート接続の注意点とテスト方法

* シリアルプリンタ(ページプリンタでないもの)のページ下端マージン

インクジェットプリンタや熱転写プリンタなどの、紙を送りながら少しずつ印刷していくタイプのプリンタは、印刷が紙の下の方まで進むと、紙をちゃんと押えることができなくなります。そのせいか、ページの下端1、2センチの部分の印刷は下手です。プリンタによってはその部分への印刷は出来ないようになっています。

たとえばEPSON MJ-5100Cの場合は、用紙下端から14mmの部分は印刷できないことになっています。また用紙上端より3〜12.5mm、用紙下端より14〜16mmの領域は「印刷可能ですが、紙送り精度は保証できません。」とマニュアルに記載されています。PCやマック用の賢いソフトウェアはこの辺をきちんと押えて印刷してくれるはずですが、UNIXからGhostscriptのドライバを使って印刷しようとするとはまります。

言われてみれば納得なのですが、実はこれを知らなかったために書類のページ番号が全て抜け落ちてしまい、どうしてなんだろうと悩みました。皆さんも気をつけて下さい。


* 他のページにあるプリンタ利用法


* 参考にしよう!!

「Solaris2と戦う」のページの 参考にしよう!!との重複があります。


<- トップページ
工学院大学機械工学科流体研

リンクはご自由に。でもメールをくれると嬉しいな。

金野 祥久  konno@researchers.jp

Last modified: Wed Dec 7 13:38:33 JST 2011