Arch Linux Printer


太久没发博客了,最近家里需要个打印机,发个打印机的配置教程水一水,顺便记录下家里打印机的解决方案。

虽然叫Arch Linux Printer,但并非全是Arch Linux相关。如果有什么不对的地方,请大火嘴下留情qaq

Printer Driver Install

大部分厂商只提供x86的驱动。我们讲述如何在x86上安装驱动。至于arm等设备可以参考brother-in-armsz这个项目来

Install CUPS

首先我们需要安装CUPS服务,参考Arch Linux CUPS

Install Provided Driver

一般来说,厂商提供的驱动只有.deb.rpm两种,我们需要自己提取并放到对应目录来实现手动安装(如果你觉得这不优雅,可以自己封个包然后用pacman本地安装)。

例如Brother 2240所提供的驱动,解压.deb包后有如下:

┬─[nacl@nacl-archlinux:~/D/hl2240lpr-2.1.0-1.i386]─[16时39分24秒]
╰─>$ tree
.
├── control.tar.gz
├── data.tar.gz
└── debian-binary

1 directory, 3 files
┬─[nacl@nacl-archlinux:~/D/hl2240lpr-2.1.0-1.i386]─[16时39分27秒]
╰─>$ 

解压data.tar.gz后有如下一坨

┬─[nacl@nacl-archlinux:~/D/hl2240lpr-2.1.0-1.i386]─[16时43分18秒]
╰─>$ tar -xzvf data.tar.gz 
./
./var/
./var/spool/
./var/spool/lpd/
./var/spool/lpd/HL2240/
./usr/
./usr/local/
./usr/local/Brother/
./usr/local/Brother/Printer/
./usr/local/Brother/Printer/HL2240/
./usr/local/Brother/Printer/HL2240/inf/
./usr/local/Brother/Printer/HL2240/inf/setupPrintcap2
./usr/local/Brother/Printer/HL2240/inf/braddprinter
./usr/local/Brother/Printer/HL2240/inf/brprintconflsr3
./usr/local/Brother/Printer/HL2240/inf/brHL2240func
./usr/local/Brother/Printer/HL2240/inf/paperinf
./usr/local/Brother/Printer/HL2240/inf/brHL2240rc
./usr/local/Brother/Printer/HL2240/lpd/
./usr/local/Brother/Printer/HL2240/lpd/filterHL2240
./usr/local/Brother/Printer/HL2240/lpd/rawtobr3
./usr/local/Brother/Printer/HL2240/lpd/psconvert2
./usr/share/
./usr/share/doc/
┬─[nacl@nacl-archlinux:~/D/hl2240lpr-2.1.0-1.i386]─[16时43分46秒]
╰─>$ tree
.
├── control.tar.gz
├── data.tar.gz
├── debian-binary
├── usr
│   ├── local
│   │   └── Brother
│   │       └── Printer
│   │           └── HL2240
│   │               ├── inf
│   │               │   ├── braddprinter
│   │               │   ├── brHL2240func
│   │               │   ├── brHL2240rc
│   │               │   ├── brprintconflsr3
│   │               │   ├── paperinf
│   │               │   └── setupPrintcap2
│   │               └── lpd
│   │                   ├── filterHL2240
│   │                   ├── psconvert2
│   │                   └── rawtobr3
│   └── share
│       └── doc
└── var
    └── spool
        └── lpd
            └── HL2240

14 directories, 12 files
┬─[nacl@nacl-archlinux:~/D/hl2240lpr-2.1.0-1.i386]─[16时44分10秒]
╰─>$ 

由于解压出来的var是一坨空的,所以我们直接略过,把usr解压出来的一堆放到本地对应目录下,应该就没问题了(

Use Driver in CUPS

驱动有了,怎么用呢?

我们算是成功安装了驱动,如何调用驱动就需要用到CUPS服务。当你连接打印机并配置服务时,会有一些默认的选项提供,但如果没有你要的驱动,CUPS服务也不知道怎么调用打印机驱动,这时我们就需要手动提供ppd文件。部分驱动会在内提供ppd文件,但如果没有提供,你可以尝试去Open Printing官网寻找(如果ppd和驱动对应不上,建议安装Open Printing提供的驱动,有Linux驱动一般都有ppd吧。。。应该)

以CUPS的web网页为例,Linux大部分客户端调用的是CUPS,所以具体过程大同小异。

访问本地CUPS,在Administer页面选择Add Printer,如果本地有可用打印机会在界面上显示,选择即可。

CUPS1

CUPS2

(如果需要共享打印机则需要勾选Share This Printer

之后在该界面选择ppd文件即可正常添加打印机

CUPS3

之后你便可以尝试打印

Enhance

p910nd远程打印

细心的你应该发现了,上面Add Printer界面所添加的打印机并非是本地打印机。要达成这个非常简单,你可以使用别的机器通过CUPS服务共享打印机;但我这边是通过wr720n刷openwrt实现远程调用打印机。重复的就不多说了,参考内容如下:

TP-Link WR720N V3 刷OpenWRT(记得看清楚路由器版本,砖了就不好玩了)

老旧设备利用打印机服务实现网络打印,并实现打印机热插拔(这个热插拔实现有点不优雅,详细看下面的)

通过OpenWRT的p910nd实现远程打印,但这有个缺点:无法手动安装驱动(或者说靠client来处理驱动文帝),相当于usbip将原始usb信息传输到服务器(这个比喻可能不太准确,但这个服务传输的就是原始信息)。

讲一下碰到的问题

1. OpenWRT源失效

lede17 后OpenWRT官方好像做过一次迁移,package的目录变了,找到对应目录换源即可

2. usb热插拔后失效

usb热插拔后p910nd会出现无法识别设备的问题,我们要做的就是写一个脚本,当监测到添加usb设备且usb设备就是我们的打印机时重启p910nd服务

/etc/hotplug.d/usb/目录下添加一个脚本20-p910nd并添加可执行权限

脚本内容具体如下:

#!/bin/sh
if [ "$ACTION" = "add" ] && [ "$PRODUCT" = "4f9/45/100" ]; then
    # 这行可以修改为你自己的打印机名称,也可以删除,不影响使用。用于检测脚本是否生效
    echo "`date`: Brother HL2240 added" >> /tmp/printer 
    # 执行重启服务
   /etc/rc.d/S50p910nd restart
fi

其中的PRODUCT变量可以通过dmseg来查看

root@LEDE:~# dmesg | grep usb
[    4.795404] usbcore: registered new interface driver usbfs
[    4.799554] usbcore: registered new interface driver hub
[    4.804994] usbcore: registered new device driver usb
[    5.505721] usb 1-1: new high-speed USB device number 2 using ehci-platform
[   11.334193] usblp 1-1:1.0: usblp0: USB Bidirectional printer dev 2 if 0 alt 0 proto 2 vid 0x04F9 pid 0x0045
[   11.342768] usbcore: registered new interface driver usblp
[   83.696068] usb 1-1: USB disconnect, device number 2
[   83.700043] usblp0: removed
[   86.382708] usb 1-1: new high-speed USB device number 3 using ehci-platform
[   86.546432] usblp 1-1:1.0: usblp0: USB Bidirectional printer dev 3 if 0 alt 0 proto 2 vid 0x04F9 pid 0x0045

找到我们想要的设备id,修改为vid/pid/100就好了(应该)。如果没问题的话你重启时会在/tmp/printer文件内看到内容:

root@LEDE:~# cat /tmp/printer 
Thu Jan  1 00:00:09 GMT 1970: Brother HL2240 added
Fri Aug 15 16:38:50 UTC 2025: Brother HL2240 added
Fri Aug 15 16:38:50 UTC 2025: Brother HL2240 added

具体原理就是利用OpenWRT hotplug来监测usb,当符合条件时重启p910nd。

AirPrint自动发现打印机

但这个打印机买来是给我家里父母用的,且二位不会用电脑,但在现在这也合理。

在次之前先来简单介绍下家里的网络配置。由于接入了dn11,家里的网络拓扑大概是这么个样子: HomeNetwork

通过wireguard连接了一个阿里云的服务器。同时家里没有配备任何的x86服务器(实际上连一台服务器都没有),手机的打印机同时缺少驱动(其实应该能找到,但是没有合适的应用),便将CUPS服务安装在阿里云上,通过阿里云调用p910nd提供的服务来实现远程连接打印机,通过CUPS来实现。

CUPS的安装和打印机的连接非常简单,和上面差不多。唯一的问题就是访问权限,这个到/etc/cups/cupsd.conf里修改一下就好了。

如果没问题的话,你现在应该能用pc通过ipp协议实现打印了;但安卓手机还是不能发现,需要我们配置avahi了。我的avahi是布置在OpenWRT上(毕竟总不能配置在云服务器上吧,多少有点神车),下面是代码:

opkg update
opkg install avahi-daemon
/etc/init.d/avahi-daemon enable
/etc/init.d/avahi-daemon start

按道理来说你现在应该能在局域网内自动发现打印机了,但我的配置多少有点神车,还需要在OpenWRT上手动添加配置文件。在/etc/avahi/services下新添加一个文件printer.service并添加可执行权限,内容如下:

<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<!DOCTYPE service-group SYSTEM "avahi-service.dtd">
<service-group>
  <name>Remote CUPS Printer</name>
  <service>
    <type>_ipp._tcp</type>
    <port>631</port>
    <txt-record>txtvers=1</txt-record>
    <txt-record>qtotal=1</txt-record>
    <txt-record>rp=printers/Home_Printer</txt-record>
    <txt-record>product=(Remote-CUPS-via-OpenWrt)</txt-record>
    <txt-record>adminurl=http://172.16.53.253:631/printers/Home_Printer</txt-record>
    <txt-record>note=Proxied CUPS Printer</txt-record>
  </service>
</service-group>

不确保对ios和mac生效,这玩意是我ai生成的玩意,实际上我在网上找不到合适的配置(可能是没用对搜索引擎导致的)

其中adminurl项是CUPS共享打印机的url,而rp项是打印机的路径,实际上就是adminurl/printers/<打印机名称>。如果却少rp项,在部分软件内会表现出能扫描到打印机但添加时会提示ipp 1030无法找到打印机,而在安卓的默认打印服务内表现为根本没有,且手动添加后会自动失效不可用。

现在,你应该能在安卓的打印服务内找到打印机了!

android

如果安卓设备还是没法找到打印机,可以用tcpdump监听下udp的5353端口,在监听的情况下重启avahi-daemon,或者demsg | grep avahi来查看avahi配置文件是否生效。tcpdump如果能看到以下内容说明没有问题。

21:20:07.235221 lan3  Out IP CR6606.lan.5353 > mdns.mcast.net.5353: 0*- [0q] 6/0/0 PTR Remote CUPS Printer._ipp._tcp.local., (Cache flush) TXT "txtvers=1" "qtotal=1" "rp=printers/Home_Printer" "product=(Remote-CUPS-via-OpenWrt)" "adminurl=http://172.16.53.253:631/printers/Home_Printer" "note=Proxied CUPS Printer", (Cache flush) SRV CR6606.local.:631 0 0, (Cache flush) AAAA fdf4:ed14:48ed::1, (Cache flush) AAAA 2409:8a28:323a:68e0::1, (Cache flush) A 172.16.53.1 (332)