Tux 知道分享是好的,第 8 部分
实际上,情况并没有那么糟糕。事实上,整个过程再次突出了 Samba 在网络环境中的灵活性。我确信大家都坐好了——让我们开始吧。
在这个小演示中,我使用的是放在我对面的笔记本电脑;连接到它的是一台 HP Laserjet 5L 打印机。这台打印机已经在 Windows 系统上配置为共享打印机。换句话说,这台 PC 已经加载了 Microsoft 网络客户端,并且使用这台 PC,我已经登录到我的工作组(我的 Samba 服务器是其中的一部分)。然后,我打开了我的打印机列表(点击“开始”,然后是“设置”,然后是“打印机”),右键单击我要共享的打印机,然后从该菜单中选择了“共享”。现在您应该看到一个如下所示的菜单。
请注意,此时您确实有机会为所讨论的资源设置密码,即共享为 HPLOCAL 的打印机(如本地 PC,但名称可以是很多东西)。现在,单击“确定”,打印机图标下应该会出现一只小手,让您知道它在网络上可用。要检查这一点,您可以使用您的老朋友 smbclient 程序。
smbclient -L speedy added interface ip=192.168.22.7 bcast=192.168.22.255 nmask=255.255.255.0 Password:
由于我们没有设置访问打印机的密码,我们只需在密码提示符下按回车键即可。这就是我们得到的。
Sharename Type Comment --------- ---- ------- PRINTER$ Disk HPLOCAL Printer CDRIVE Disk IPC$ IPC Remote Inter Process Communication
那么,您到底如何从 Linux 系统打印到这台打印机呢?嗯,正如您可能期望的那样,有不止一种方法可以做到这一点。一种相当简单的方法是使用非常灵活的 smbclient 程序连接到共享打印机。
$ smbclient "//speedy/hplocal" added interface ip=192.168.22.100 bcast=192.168.22.255 nmask=255.255.255.0 Password: smb: >
假设我有一个名为“a_file”的文件,其中包含三行。像这样
This is line 1 This is line 2 This is line 3
只需在 smbclient 提示符下键入 print a_file,您的打印作业就应该打印出来。这对于文本文件来说很好,但即使这样也存在一些问题。在我的例子中,打印输出更像这样。
This is line 1 This is line 2 This is line 3
你们中读过我关于“驯服打印机和打印的恐怖”系列文章(第 1、2、3 和 4 部分)的人会知道这就是 阶梯效应。
我们可以通过在每行末尾添加一个 Control-M 字符来解决这个问题,但这远非实用。相反,在 smb:> 提示符下键入 translate。系统会响应如下
CR/LF<->LF and print text translation now on
我们使用之前的相同 print a_file 命令再次发送文件,瞧!这解决了阶梯效应,而无需编辑我们的文件,但这仍然是一种笨拙的打印方式。毕竟,我们有定义打印机的应用程序,当我们从命令行打印时,我们通常使用 lpr 命令。为了解决这个问题,Samba 附带了一个小程序(实际上是一个 Bourne shell 脚本),称为 smbprint。对于那些从头开始构建 Samba 的人来说,smbprint 脚本位于源代码树下的 examples/printing 中。如果您的 Samba 版本是预先安装的,您可能会发现它已经位于 /usr/bin 下。
要使用 smbprint,我们需要在 /etc/printcap 文件中创建一个条目。这是我为上述配置创建的条目
## Samba printer hplocal: :sd=/var/spool/samba/hplocal: :af=/var/spool/samba/hplocal/hplocalacct: :if=/usr/bin/smbprint: :lp=/dev/null:
sd 是后台打印目录,打印作业在发送到共享打印机之前将在此处进行后台打印。然后我们有 af 参数,它指定一个记帐文件(您不必创建该文件,但让它转到您刚刚为 sd 定义的同一目录)。下一个条目 if 是您的打印过滤器,即 smbprint 脚本。最后,我们有一个虚拟打印设备,我们将其设置为 /dev/null。
顺便说一句,您可以将 smbprint 脚本复制到另一个位置(可能是 /usr/local/bin),并将其命名为您喜欢的任何名称。我现在提到这一点是因为您可能想要为不同的打印机自定义过滤器。稍后会详细介绍。
最后,您需要在后台打印目录中创建一个 .config 文件,该文件定义了有关我们想要使用的 PC 连接打印机的某些信息(注意 config 前面的点)。再次使用我自己的示例,这是我的设置
server=speedy service=hplocal password=""
如果您在共享打印机上使用用户名和密码安全,您也可以设置一个“user=user_name”参数。完成此处操作后,尝试打印一些内容。
/usr/games/fortune -l | lpr -P hplocal
如果(像我一样)您发现自己的打印输出与之前一样存在阶梯效应问题,那么是时候修改您的 smbprint 过滤器了。查找说 TRANS=0 的行,并将 0 更改为 1。现在再次尝试打印作业,一切应该都正常了。此外,某些版本的脚本没有设置 TRANS 变量。相反,查看脚本底部,查找一行说 # echo translate 的行,并删除注释标记。
啊,是的!后面的人 说得对。这对于仅文本打印机来说一切都很好,但是 Postscript 呢?PCL3 呢?我们可能需要的其他所有打印机格式呢?我们该怎么办?是时候多了解一点过滤器了。如果您查看 smbprint 脚本的末尾,您会看到过滤器的核心。
( # NOTE You may wish to add the line `echo translate' if you want automatic # CR/LF translation when printing. # echo translate echo "print -" cat ) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $server -N -P >> $logfile
我不会在这里对过滤器进行大量讨论,因为我过去已经详细讨论过这个问题(请参阅“驯服打印机和打印的恐怖”第 1 和 2 部分以进行复习)。我要告诉您的是,由于这是一个充当过滤器的脚本,您可以 创建自己的过滤器。我所做的是:我摆脱了您在上面看到的所有行(我的实际过滤器),我替换了我自己的过滤器,一个基于该打印机系列第二部分的 ljet4 过滤器。这是现在的新过滤器,旧过滤器被注释掉了。
#( # NOTE You may wish to add the line `echo translate' if you want automatic # CR/LF translation when printing. # echo translate # echo "print -" cat | /usr/bin/gs -q -dNOPAUSE -sDEVICE=ljet4 -r300 -sPAPERSIZE=letter -sOutputFile=- - | /usr/bin/smbclient "\\\\$server\\$service" $password -U $server -N -P -c "printmode graphics ; print -" >> $logfile
每行末尾的反斜杠是脚本中的续行符,为了便于阅读而添加的。在您的脚本中,您可以轻松地将其设为连续的一行。那么,让我们来检查一下,好吗?这里要特别注意的是,我们正在构建一个 Ghostscript 过滤器,并为我们的打印机指定合适的驱动程序。然而,最重要的是最后一行附近的末尾。我们设置 printmode graphics 是因为 smbclient 需要知道我们正在发送图形信息而不是文本。字符串的最后一部分(; print -)确保整个内容随后被视为打印作业。
我想强调一下,这是 smbprint 脚本的副本。因此,必须使其在您放置它的任何位置都可执行。我将我的脚本称为 ljetfilter,我将其放在 /usr/local/bin 中。然后,我使用 chmod +x /usr/local/bin/ljetfilter 使其可执行。最后,我修改了我的 /etc/printcap,以便“if”行如下所示。
:if=/usr/local/bin/ljetfilter:
此时,我几乎可以打印任何东西,包括 Postscript 文件。
lpr -Phplocal /path_to/printfile.ps
既然我已经信守诺言,现在是时候结束今天的工作了。感谢大家对本系列文章的热烈反响,感谢大家让我保持警惕 <在此处插入适当的笑脸>。在我们下次在系统管理员专栏见面之前,请记住您的妈妈说过的话,“分享是好的”。并记住 Tux 也知道这一点。
正在查找本系列的往期文章? 点击此处获取列表。
电子邮件: ljeditors@ssc.com