Tux 知道分享是好的,第 8 部分

作者:Marcel Gagné

实际上,情况并没有那么糟糕。事实上,整个过程再次突出了 Samba 在网络环境中的灵活性。我确信大家都坐好了——让我们开始吧。

在这个小演示中,我使用的是放在我对面的笔记本电脑;连接到它的是一台 HP Laserjet 5L 打印机。这台打印机已经在 Windows 系统上配置为共享打印机。换句话说,这台 PC 已经加载了 Microsoft 网络客户端,并且使用这台 PC,我已经登录到我的工作组(我的 Samba 服务器是其中的一部分)。然后,我打开了我的打印机列表(点击“开始”,然后是“设置”,然后是“打印机”),右键单击我要共享的打印机,然后从该菜单中选择了“共享”。现在您应该看到一个如下所示的菜单。

Tux Knows It's Nice to Share, Part 8

请注意,此时您确实有机会为所讨论的资源设置密码,即共享为 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

你们中读过我关于“驯服打印机和打印的恐怖”系列文章(第 1234 部分)的人会知道这就是 阶梯效应

我们可以通过在每行末尾添加一个 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

我不会在这里对过滤器进行大量讨论,因为我过去已经详细讨论过这个问题(请参阅“驯服打印机和打印的恐怖”第 12 部分以进行复习)。我要告诉您的是,由于这是一个充当过滤器的脚本,您可以 创建自己的过滤器。我所做的是:我摆脱了您在上面看到的所有行(我的实际过滤器),我替换了我自己的过滤器,一个基于该打印机系列第二部分的 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

加载 Disqus 评论