LPDの起動
/etc/rc.confを編集します。" -r " はリモートプリンターでも自分のPCの/etc/printcapで指定したフィルタを使用する設定です。etc/default/rc.conf には "-s" が設定されていますが、ネットワーク・クライアントからLPR印刷を許可させたいので取ります。また、” -l " を付けると/etc/printcapで指定したログファイルへ詳しいログを出力することができます。
編集後、/etc/rc.d/lpd start で起動させます。
lpd=YES
lpd_flags="-r"
ローカルプリンターを使う設定
(・・・まだやってない。やったら書く)
リモートプリンターを使う設定
LPDサーバーが起動しているリモートプリンター(ESC/P)へ印刷できるように設定します。/etc/printcapを編集します。
lp|EPSON:\
:sh:lp=:rm=192.168.10.75:rp=lp:\
:sd=/var/spool/output/remote:\
:lf=/var/log/lpd-errs:
テスト印字
lptestを使用しテスト文字を32桁、5行で印字します。
> lptest 32 5 | lpr
実行すると以下のように印字されます。
!"#$%&'()*+,-./0123456789:;<=>?@
"#$%&'()*+,-./0123456789:;<=>?@A
#$%&'()*+,-./0123456789:;<=>?@AB
$%&'()*+,-./0123456789:;<=>?@ABC
%&'()*+,-./0123456789:;<=>?@ABCD
英字のみのファイルならばこれだけで印刷できます。lprコマンドで.loginファイルを印刷してみます。(漢字は化けてしまいます)
> lpr .login
漢字が印刷できるフィルタ
文字コードはESC/Pの文字コードであるJISコードへ変換します。ただし漢字シフトはJISコードとは違うのでESC/Pの漢字シフトへ変換します。
このファイルは/usr/libexec/lprへescp-jpで保管します。それから chmod +x で実行権を付けます。
#!/bin/sh
PATH="$PATH":/usr/pkg/sbin:/usr/pkg/bin
# JIS-KANJI-IN ( ESC $B ) = '\x1b$B'
# JIS-KANJI-OUT ( ESC (B ) = '\x1b(B'
# ESC/P-KANJI-IN ( FS & ) = '\x1c&'
# ESC/P-KANJI-OUT ( FS . ) = '\x1c.'
ESC=`printf '\x1b'`
FS=`printf '\x1c'`
printf "\x1b@" #プリンターのリセット
nkf -j | sed -e "s/$ESC\$B/$FS\&/g" -e "s/$ESC(B/$FS./g" && exit 0
exit 2
GNU sedならば16進数を扱うことができるので、もうちょっと簡単なsedの指定ができるかもしれません。
それから、netbsdのechoコマンドはエスケープ文字が使えないのでprintfコマンドを使用します。
そして、/etc/printcapにフィルタの指定を追加します。
ちなみに、このフィルタは、ESC/POSが搭載されている小型サーマルプリンターでも使えます。(実はその為に作りました)
lp|EPSON:\
:sh:lp=:rm=192.168.10.75:rp=lp:\
:sd=/var/spool/output/remote:\
:lf=/var/log/lpd-errs:\
:if=/usr/libexec/lpr/escp-jp:
後日、気が付きました・・・
半角カタカナは正常に変換できません。ESC/Pのコード体系が2バイト文字(漢字)はJISで1バイト文字(アルファベットや半角カナ等)はSJISのようです。
ネットワーク・クライアントからのLPR印刷を許可する
"-s" は付けずにLPDを起動させます。/etc/hosts.lpdを編集し、印刷を許可するネットワーク・クライアントのホスト名を入れます。ホスト名なので、予め/etc/hosts等に登録してある必要があります。
初期値は全て拒否で ' - ' が設定してあります。全て許可する場合には ' + ' にします。
その他
Windowsにて・・・
WindowsのStandard TCP/IP PortはLPRと同じと思ってたら違ってた。参照先
WindowsでLPR Portを使いたければ、「UNIX容印刷サービス」をインストールする必要があります。参照先
あと、コマンドプロンプトでlprコマンドが使えます。
メモ
リコーのエミュレーション名
R55: IBM 5577, R98:NEC PR201H, R16: EPSON ESC/P
ESC/Pプリントフィルタ
シェルプログラムの勉強で作りました。一時ファイルを使わなくてもいいのでは?という感じもありますが勉強なので。
ちゃんと半角カタカナも印刷出来ます。
#!/bin/sh
# ESC/P プリントフィルタ
# JIS
c_kanji=`printf '\e$B'` # JIS X0208-1983
c_katakana=`printf '\e(I'`
c_ascii=`printf '\e(B'`
# ESC/P
c_escp_kst=`printf '\x1c&'`
c_escp_ken=`printf '\x1c.'`
# その他
c_befor_mode='_blank'
# 一時ファイル作成
c_tmp_file=`mktemp -t escptmp`
# 一時ファイルの削除
trap "rm -f $c_tmp_file" EXIT
# サブルーチン
fn_short_len () {
d_tmp_len=`awk -v p_word="$1" -v p_mode="$2" 'BEGIN{print index(p_word, p_mode)}'`
if [ "$d_tmp_len" -ne 0 -a "$d_tmp_len" -lt "$3" ] ; then
echo "$d_tmp_len"
else
echo "$3"
fi
}
#
# 主要処理
#
# プリンターリセット
printf '\x1b@'
while read r_stdin
do
c_wk_stdin=`echo -n "$r_stdin" | nkf -jx`
cat /dev/null > "$c_tmp_file"
while :
do
c_tmp_mode=`echo -n "$c_wk_stdin" | cut -b 1-3`
if [ "$c_tmp_mode" = "$c_kanji" \
-o "$c_tmp_mode" = "$c_katakana" \
-o "$c_tmp_mode" = "$c_ascii" ] ; then
c_wk_stdin=`echo -n "$c_wk_stdin" | cut -b 4-`
else
if [ "$c_befor_mode" = "$c_kanji" \
-o "$c_befor_mode" = "$c_katakana" ] ; then
c_tmp_mode="$c_befor_mode"
else
c_tmp_mode="$c_ascii"
fi
fi
d_len=`awk -v p_word="$c_wk_stdin" 'BEGIN{print length(p_word)}'`
if [ "$d_len" -eq 0 ] ; then
break
fi
c_mode="$c_tmp_mode"
d_len=`expr "$d_len" + 1`
d_len=`fn_short_len "$c_wk_stdin" "$c_kanji" "$d_len"`
d_len=`fn_short_len "$c_wk_stdin" "$c_katakana" "$d_len"`
d_len=`fn_short_len "$c_wk_stdin" "$c_ascii" "$d_len"`
d_len=`expr "$d_len" - 1`
c_pr_stdin=`echo -n "$c_wk_stdin" | cut -b 1-"$d_len"`
echo -n "$c_mode" >> "$c_tmp_file"
echo -n "$c_pr_stdin" >> "$c_tmp_file"
printf '\n' >> "$c_tmp_file"
d_len=`expr "$d_len" + 1`
c_wk_stdin=`echo -n "$c_wk_stdin" | cut -b "$d_len"-`
done
#
#
while read c_wk_stdin
do
c_tmp_mode=`echo -n "$c_wk_stdin" | cut -b 1-3`
case "$c_tmp_mode" in
"$c_kanji" )
c_wk_stdin=`echo -n "$c_wk_stdin" | cut -b 4-`
echo -n "$c_escp_kst"
echo -n "$c_wk_stdin"
echo -n "$c_escp_ken"
;;
* )
echo -n "$c_wk_stdin" | nkf -Jsx
;;
esac
done < "$c_tmp_file"
printf '\n'
done
で、やはり・・・
でかいプログラムはUNIXらしくないので、一時ファイルも使わず、小さく組んでみようとしました。あまり代わり映えないですが。
!/bin/sh
# ESC/P プリントフィルタ
# JIS
c_esc=`printf '\e'`
c_kanji='$B' # 漢字
# ESC/P
c_escp_kst=`printf '\x1c&'`
c_escp_ken=`printf '\x1c.'`
#プリンターのリセット
printf '\x1b@'
while read r_stdin
do
og_stdin=`echo -n "$r_stdin" | nkf -jx`
d_next=1
while :
do
og_stdin=`echo -n "$og_stdin" | cut -b "$d_next"-`
d_len=`awk -v p_word="$og_stdin" 'BEGIN{print length(p_word)}'`
d_pos=`awk -v p_word="$og_stdin" -v p_esc="$c_esc" 'BEGIN{print index(p_word, p_esc)}'`
if [ "$d_len" -eq 0 ] ; then
break
elif [ "$d_pos" -eq 0 ] ; then
pr=`echo -n "$og_stdin" | nkf -Jsx`
echo -n "$pr"
break
elif [ "$d_pos" -gt 1 ] ; then
d_end=`expr "$d_pos" - 1`
pr=`echo -n "$og_stdin" | cut -b 1-"$d_end" | nkf -Jsx`
echo -n "$pr"
d_next="$d_pos"
continue
elif [ "$d_len" -eq 3 ] ; then
break
fi
#
#
wk_stdin=`echo -n "$og_stdin" | cut -b 2-`
d_pos=`awk -v p_word="$wk_stdin" -v p_esc="$c_esc" 'BEGIN{print index(p_word, p_esc)}'`
# d_end=`expr "$d_pos" - 1`
d_end="$d_pos"
if [ "$d_end" -eq 0 ] ; then
d_end="$d_len"
fi
d_next=`expr "$d_end" + 1`
c_mode=`echo -n "$og_stdin" | cut -b 2-3`
if [ "$c_mode" = "$c_kanji" ] ; then
echo -n "$c_escp_kst"
pr=`echo -n "$og_stdin" | cut -b 4-"$d_end"`
echo -n "$pr"
echo -n "$c_escp_ken"
else
pr=`echo -n "$og_stdin" | cut -b 1-"$d_end" | nkf -Jsx`
d_end=`expr "$d_end" - 3`
pr=`echo -n "$pr" | cut -b 1-"$d_end"`
echo -n "$pr"
fi
done
printf '\n'
done