Linux 版 (精华区)

发信人: tcpip (高级草包), 信区: Linux
标  题: 打印及传真 - 11. 如何打印到网络打印机
发信站: 紫 丁 香 (Tue Apr 11 19:19:53 2000) WWW-POST

打印及传真 - 11. 如何打印到网络打印机  


Lpd 的一个特性便是可以通过网络将报表打印到实体连接在其它机器上的打印机. 只要仔
细地组合 filter 脚本文件和相关的工具程序, 你就可以让 lpr 得以透通地 
(transparently) 打印到各种网络上的打印机. 


11.1 打印至 Unix/lpd 
要让远端的机器能够使用你的打印机打印, 你必须将远端机器列名在 /etc/hosts.equiv 
或是 /etc/hosts.lpd 文件之中. (要注意 hosts.equiv 还有其它很多作用; 如果你要将
一部机器列在这儿, 请确定你知道你在做什么). 你也可以利用 rs 属性来限定其它机器
上的某些特定使用者才能使用你的打印机. 请看 lpd 的在线手□以取得这方面的讯息. 



用 lpd
要打印到另一部机器, 你要在 /etc/printcap 中加上这样的记录, 

# REMOTE djet500
lp|dj|deskjet:\
        :sd=/var/spool/lpd/dj:\
        :rm=machine.out.there.com:\
        :rp=printername:\
        :lp=/dev/null:\
        :sh:

请注意在本地的机器还是要有一个由 lpd 管理的打印暂存器目录. 如果远端的机器离线
或是忙不过来, 打印工作会留在本地的暂存区中直到送出去为止. 

用 rlpr
你也可以用 rlpr 将打印工作直接送到远端机器的队列中, 省下设定 lpd 的麻烦. 假如
你偶尔才要打印到其它不同的打印机, 这个方法就最有用. 引一段 rlpr 的声明: 


rlpr 利用 TCP/IP 将打印工作送到网络上任何位置的 lpd 服务器. 


与 lpr 不同的是, 你打印来源端的机器 *不需要* 明确地知道远端的打印机, (例如通过
 /etc/printcap) 因此有相当大的弹性, 管理的负担也比较轻. 



rlpr 可以用在任何使用传统 lpr 的地方, 而且和传统的 BSD lpr 兼容. 


rlpr 最大的好处在於可以 *从任何地方打印到任何地方* 而不用管打印来源端的系统设
定. 它可以像传统的 lpr 做为一个 filter, 而让在远端机器上执行的客户端像 
netscape, xemacs 等能够轻易地打印报表到你本地的机器. 


你可以在 SunSite 找到 rlpr. 


11.2 打印到 Win95, WinNT, LanManager, 或 Samba 上的打印机 
在 Printing to Windows mini-HOWTO 中有比这儿更多的信息. 

通过 smbclient 这个程序 (samba 套件的一部份) 可以将 lpd 队列导向到架构在 
TCP/IP 之上的 SMB 打印服务. Samba 包含了一个脚本文件 smbprint 来做这件事. 简单
地说, 替这样的打印机在打印暂存器工作目录 (spool directory) 中加上设定文件, 然
后将 if 设为 smbprint 脚本文件. 

在 /etc/printcap 中的记录看起来应该像这个样子: 

lp|remote-smbprinter:\
    :lp=/dev/null:sh:\
    :sd=/var/spool/lpd/lp:\
    :if=/usr/local/sbin/smbprint:

你应该阅读一下 smbprint 脚本文件中的说明以得到更多相关的讯息. 

你也可以不管 lpd, 直接用 smbclient 将文件送到 SMB 打印服务. 请参照在线手□. 


11.3 打印到 NetWare 上的打印机 
ncpfs 套件中包含了一个名为 nprint 的工具程序, 它提供如同 smbprint 一般的功能, 
只不过适用的对象是 Netware. 你可以在 SunSite 取得 ncpfs. 下面是从 0.16 版的 
LSM 中节录出来的: 

With ncpfs you can mount volumes of your netware server under Linux. You can 
also print to netware print queues and spool netware print queues to the 
Linux printing system. You need kernel 1.2.x or 1.3.54 and above. ncpfs does 
NOT work with any 1.3.x kernel below 1.3.54. 
利用 ncpfs, 你可以在 Linux 下挂上你的 netware 服务器上的目录. 你也可以打印到 
netware 的打印队列以及将 netware 的打印队列排存(spool) 到 Linux 的打印系统. 你
需要 1.2.x 或 1.3.54 以上(含 1.3.54) 的核心. ncpfs 无法在 1.3.54 以前的任何一
版 1.3.x 核心下运作. 


要使 nprint 通过 lpd 运作, 你要写个小小的 shell script 将 stdin 打印到 
Netware 上的打印机, 并设成 lpd 打印队列的 if. 你可能会有: 

sub2|remote-NWprinter:\
        :lp=/dev/null:sh:\
        :sd=/var/spool/lpd/sub2:\
        :if=/var/spool/lpd/nprint-script:

nprint-script 看起来可能大致上像: 
#! /bin/sh
# You should try the guest account with no password first!
/usr/local/bin/nprint -S net -U name -P passwd -q printq-name -


11.4 打印到 EtherTalk (Apple) 上的打印机 
netatalk 套件包含了像 nprint 和 smbclient 的东西. 其他人已经写下了使用 Apple 
网络打印的程序, 远比我所能写的好得多; 请参阅 Linux Netatalk-HOWTO. 


11.5 打印到 HP 或其它的以太网络(ethernet) 打印机 
有些 HP 和其它厂牌的打印机提供了可以直接用 lpd 打印的以太网络界面. 你应该遵照
打印机或其网络界面所附的指示, 但是通常这种打印机上 "跑" 的是 lpd, 而且提供一到
多个你可以使用的队列. 举例来说, 一部 HP 可能可以用这样的 printcap: 

lj-5|remote-hplj:\
        :lp=/dev/null:sh:\
        :sd=/var/spool/lpd/lj-5:\
        :rm=printer.name.com:rp=raw:

具有 Jet Direct 界面的 HP Laserjet 打印机通常支持两个内建的 lpd 队列 - "raw" 
接受 PCL (可能也接受 Postscript), 以及 "text" 接受单纯的 ascii (而且会自动地克
服阶梯效应). 如果你有的是 JetDirect Plus3 三埠的界面, 队列的名称则为 "raw1", 
"text2" 等等. 

在一个大型的环境, 特别是个有些打印机不支持 PostScript 的大型环境中, 架设一部专
门的打印服务器, 让所有的机器都打印到这部服务器并让所有的 ghostscript 工作都在
这部服务器上面执行可能会有用. 

这样子也可以让你的 Linux 做为打印机的排存服务器(spool server), 如此一来你的网
络使用者便可以快一点完成他们的打印工作然后继续手边的事情, 而不必等待打印机印完
先前别人所送出的报表. 

要这样做, 先在你的 linux 机器上设定一个打印队列指到配有以太网络界面 HP LJ (如
前所述). 现在将所有在你局域网上的客户端设定指到这个 Linux 队列 (如前面范例中的
 lj-5). 

有些 HP 网络打印机似乎不理会客户端送出的标题页(banner page) 设定. 你可以关掉它
们内部自行产生的标题页, 用 telnet 连接到打印机, 按两下 return 键, 打入 
"banner: 0", 接著打入 "quit". 还有其它可以调整的设定也是用这个方式; 打入 "?" 
可以看到它们的表列. 


打印到比较旧的 HP 打印机
有些打印机 (或是将打印机连上网络的装置) 只支持很阳春的 TCP 连线. 在这一类中值
得注意的是早期的 JetDirect (包括一些 JetDirectEx) 接口卡. 基本上, 要打印到这类
的打印机, 你必须建立到某个特定埠 (典型是在 9100, 或是三埠机种的 9100, 9101 和 
9102) 的 TCP 连接, 然后将你的报表送进去. 这可以用 Perl 来实做, 或是用其它的方
式: 


#!/usr/bin/perl
# Thanks to Dan McLaughlin for writing the original version of this
# script (And to Jim W. Jones for sitting next to Dan when writing me
# for help ;)

$fileName = @ARGV[0];

open(IN,"$fileName") || die "Can't open file $fileName";

$dpi300     = "\x1B*t300R";
$dosCr      = "\x1B&k3G";
$ends = "\x0A";

$port =  9100 unless $port;
$them = "bach.sr.hp.com" unless $them;

$AF_INET = 2;
$SOCK_STREAM = 1;
$SIG{'INT'} = 'dokill';
$sockaddr = 'S n a4 x8';

chop($hostname = `hostname`);
($name,$aliases,$proto) = getprotobyname('tcp');
($name,$aliases,$port) = getservbyname($port,'tcp')
    unless $port =~ /^\d+$/;;
($name,$aliases,$type,$len,$thisaddr) =
        gethostbyname($hostname);
($name,$aliases,$type,$len,$thataddr) = gethostbyname($them);
$this = pack($sockaddr, $AF_INET, 0, $thisaddr);
$that = pack($sockaddr, $AF_INET, $port, $thataddr);

if (socket(S, $AF_INET, $SOCK_STREAM, $proto)) {
#    print "socket ok\n";
}
else {
    die $!;
}
# Give the socket an address.
if (bind(S, $this)) {
#    print "bind ok\n";
}
else {
    die $!;
}

# Call up the server.

if (connect(S,$that)) {
#    print "connect ok\n";
}
else {
    die $!;
}

# Set socket to be command buffered.

select(S); $| = 1; select(STDOUT);

#    print S "@PJL ECHO Hi $hostname! $ends";
#    print S "@PJL OPMSG DISPLAY=\"Job $whoami\" $ends";
#    print S $dpi300;

# Avoid deadlock by forking.

if($child = fork) {
    print S $dosCr;
    print S $TimesNewR;

    while () {
        print S;
    }
    sleep 3;
    do dokill();
} else {
    while() {
        print;
    }
}

sub dokill {
    kill 9,$child if $child;
}


11.6 替远端打印机执行 if 
lpd 一个不寻常的地方在於如果是远端打印机, if 不会被执行. 如果你发现你需要执行 
if, 你可以设定双重队列(double queue) 并重新队列报表. 举个例子, 看一下这个 
printcap: 

lj-5:\
        :lp=/dev/null:sh:\
        :sd=/var/spool/lpd/lj-5:\
        :if=/usr/lib/lpd/filter-lj-5:
lj-5-remote:lp=/dev/null:sh:rm=printer.name.com:\
        :rp=raw:sd=/var/spool/lpd/lj-5-raw:

和相关的 filter-lj-5 脚本文件(script): 
#!/bin/sh
gs  -q -dSAFER -sOutputFile=- - | \
        lpr -Plj-5-remote -U$5

只有在 lpr 以监控程序(daemon) 模式执行的时候, -U 选项才有作用, 这个选项会正确
地设定第二重队列中的送件人姓名. 你可能应该用更可靠的方法取得送件人姓名, 因为有
些时候它并不是第五个参数. 请参照 printcap 的在线手□. 


11.7 从 Windows 打印 
利用 SAMBA 套件可以直接支持以 SMB 协议从 Windows (或许 OS/2) 客户端打印到 
Linux 服务器, 这个套件同时也支持将你的 Linux 文件系统共享给 Windows 客户端. 

Samba 包含了相当完整的文件, 也有一份很不错的 Samba FAQ 包括到这方面的内容. 你
可以在 Linux 上设置 magic filter 然后以 PostScript 打印, 或是在每一部 Windows 
机器上安装打印机专用的驱动程序然后为他们设定一个不用任何 filter 的队列. 使用 
Windows 驱动程序有些时候会有比较好的输出, 但是如果有很多部 Windows 机器, 管理
者就比较麻烦. 所以先试试看 PostScript 吧! 


11.8 从 Apple 打印 
Netatalk 支持由 Apple 客户端通过 EtherTalk 打印. 请参照 Netatalk HOWTO Page 以
取得更进一步的信息. 


11.9 从 Netware 打印 
ncpfs 套件含有一个叫作 pserver 的监控程序(daemon) 可以提供服务给 NetWare 的打
印队列. 据我所了解, 这个系统必须搭配 Bindery-based 的 NetWare, 像是 2.x, 3.x, 
或是使用 bindery 存取的 4.x 版本. 

要取得更进一步关于 ncpfs 和其 pserver 程序的信息, 请参照 ncpfs 的 FTP 站

--
"这一千多年没写诗了?"
"写了, 不过只写了两句."
"千年得两句, 一定是万古丽句了. 念来听听."
"好吧, 我现丑了" 太白星清了清嗓子, 浑厚的男中音在天庭响起:
大海啊, 都是水;
骏马啊, 四条腿;

※ 来源:·紫 丁 香 bbs.hit.edu.cn·[FROM: tcpip.hit.edu.c] 
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:197.727毫秒