我需要在 Debian (KDE) 环境下通过 USB 连接 HP LaserJet M14-M17 打印机打印几张试卷。打印机插入后能够被系统识别并出现在设备列表中,但实际发送打印任务时,状态显示"打印完成",打印机却毫无反应,仅指示灯象征性地闪烁了两下。值得注意的是,打印选项中没有双面打印。
第一反应是检查 HPLIP 。系统的 HPLIP 版本是 3.22.10 。随后执行 sudo hp-setup -i ,系统正确检测到了打印机并匹配了对应的 PPD 文件(hp-laserjet_m14-m17.ppd)。但在打印测试页时,终端输出以下错误:
error: Channel write error
error: Device is busy or in an error state.
打印机依然没有反应。HPLIP 虽然识别了设备型号,但实际的数据通信失败了。这就很奇怪了。
查询发现, HP LaserJet M14-M17 是一款支持 IPP Everywhere 的打印机,通过 USB 连接时使用的是 IPP over USB 协议,而非传统的 USB 批量传输。在 Debian 中,负责处理该协议的是 ipp-usb 守护进程。
我尝试检查 ipp-usb 的状态。
bash
systemctl status ipp-usb
○ ipp-usb.service - Daemon for IPP over USB printer support
Loaded: loaded (/usr/lib/systemd/system/ipp-usb.service; static)
Active: inactive (dead)
Docs: man:ipp-usb(8)
Apr 25 18:40:15 localhost systemd[1]: Started ipp-usb.service - Daemon for IPP over USB printer support.
Apr 25 18:41:04 localhost systemd[1]: ipp-usb.service: Deactivated successfully.
服务处于 inactive (dead) 状态,且日志中显示它曾被多次启动但均在短时间内退出。也许是 ipp-usb 本身的问题?
bash
systemctl status ipp-usb.socket
Unit ipp-usb.socket could not be found.
socket 单元不存在。ipp-usb 并非通过 socket 激活。
原来,服务反复退出的真正原因是打印机未开机------ipp-usb 在 udev 模式下运行时,如果没有检测到 IPP over USB 设备,就会自动退出。
打开打印机后,先用 lsusb 确认设备已被系统识别:
bash
lsusb | grep -i hp
Bus 001 Device 006: ID 03f0:be2a HP, Inc HP LaserJet M14-M17
bash
systemctl status ipp-usb
● ipp-usb.service - Daemon for IPP over USB printer support
Loaded: loaded (/usr/lib/systemd/system/ipp-usb.service; static)
Active: active (running) since Sat 2026-04-25 19:03:40 CST; 2min 2s ago
Main PID: 3904 (ipp-usb)
Tasks: 12 (limit: 4306)
Memory: 14.2M (peak: 15M)
CPU: 98ms
CGroup: /system.slice/ipp-usb.service
└─3904 /usr/sbin/ipp-usb udev
Apr 25 19:03:40 localhost systemd[1]: Started ipp-usb.service - Daemon for IPP over USB printer support.
ipp-usb 成功保持运行,且命令行参数为 udev,印证了它以 udev 模式工作。查看journal,其中却只记录了 systemd 的启停信息,看不到 ipp-usb 自身的日志。通过 ipp-usb -h 查看帮助信息,发现它支持 debug 模式。
Usage:
ipp-usb mode [options]
Modes are:
standalone - run forever, automatically discover IPP-over-USB
devices and serve them all
udev - like standalone, but exit when last IPP-over-USB
device is disconnected
debug - logs duplicated on console, -bg option is
ignored
check - check configuration and exit
status - print ipp-usb status and exit
bash
systemctl stop ipp-usb
ipp-usb debug
===============================
ipp-usb started in "debug" mode, pid=4190
ctrlsock: listening at "/var/ipp-usb/ctrl"
+ PNP Bus 001 Device 006: added
===============================
+ Found new device. VID:PID = 03f0:be2a
HWID quirks: EMPTY
Loading quirks for model: "HP LaserJet M14-M17"
Device quirks:
[*]
; (/usr/share/ipp-usb/quirks/default.conf:5)
http-connection = ""
+ Bus 001 Device 006: opened HP LaserJet M14-M17
Device info:
USB Port: 2
Ident: 03f0-be2a-VN50B02739-HP-LaserJet-M14-M17
Manufacturer: HP
Product: HP LaserJet M14-M17
SerialNumber: VN50B02739
BasicCaps: print,http
USB stack parameters
authorized_default: 1
autosuspend: 2
blinkenlights: N
initial_descriptor_timeout: 5000
nousb: N
old_scheme_first: N
quirks:
usbfs_memory_mb: 16
usbfs_snoop: N
usbfs_snoop_max: 65536
use_both_schemes: Y
USB interfaces:
Config Interface Alt Class SubClass Proto
1 0 0 7 1 2
1 1 0 255 4 1
* 1 1 1 7 1 4
1 2 0 255 4 1
* 1 2 1 7 1 4
1 3 0 255 4 1
* 1 3 1 7 1 4
USB[0]: open: Bus 001 Device 006 Interface 1 Alt 1
USB[1]: open: Bus 001 Device 006 Interface 2 Alt 1
USB[2]: open: Bus 001 Device 006 Interface 3 Alt 1
> HTTP[000]: POST ipp://localhost:60000/ipp/print
> HTTP[000]: request body: got 461 bytes; closed
> HTTP[000]: body is small (461 bytes), prefetched before sending
USB[0]: connection allocated, 1 in use: a-- --- ---
HTTP[000]: connection 0 allocated
USB[0]: zero-size read
...(此处省略大量 zero-size read)
< HTTP[000]: POST ipp://localhost:60000/ipp/print - 200 OK
USB[0]: zero-size read
...(此处省略大量 zero-size read)
< HTTP[000]: response body: got 1566 bytes; EOF
USB[0]: connection released, 0 in use: --- --- ---
< HTTP[000]: done with response body
IPP FaxOut service not in capabilities
> HTTP[001]: GET http://localhost:60000/eSCL/ScannerCapabilities
> HTTP[001]: body is empty, sending as is
USB[1]: connection allocated, 1 in use: --- a-- ---
HTTP[001]: connection 1 allocated
USB[1]: zero-size read
...(此处省略大量 zero-size read)
< HTTP[001]: GET http://localhost:60000/eSCL/ScannerCapabilities - 404 Not Found
< HTTP[001]: client has gone; draining response from USB
! ESCL: eSCL: HTTP status: 404 Not Found
> HP LaserJet M16a (435CA7): _printer._tcp TXT record:
usb_SER=VN50B02739
usb_HWID=03f0&be2a
> HP LaserJet M16a (435CA7): _ipp._tcp TXT record:
air=none
mopria-certified=1.3
rp=ipp/print
priority=50
kind=document,envelope,photo
PaperMax=legal-A4
UUID=564e3530-4230-3237-3339-c46516435ca7
Color=F
Duplex=F
note=
qtotal=1
usb_MDL=HP LaserJet M14-M17
usb_MFG=HP
usb_CMD=PJL,PML,PWG_RASTER,URP
ty=HP LaserJet M14-M17
product=(HP LaserJet M14-M17)
pdl=application/PCLm,application/octet-stream,image/pwg-raster
txtvers=1
adminurl=http://localhost:60000
Fax=F
Scan=F
usb_SER=VN50B02739
usb_HWID=03f0&be2a
> HP LaserJet M16a (435CA7): _http._tcp TXT record:
> HP LaserJet M16a (435CA7): _ipp-usb._tcp TXT record:
DNS-SD: HP LaserJet M16a (435CA7) (USB): trying
USB[1]: connection released, 0 in use: --- --- ---
< HTTP[001]: done with response body
DNS-SD: FQDN: "linux.local"
DNS-SD: FQDN: "linux.local"->"localhost"
DNS-SD: +subtype: "_universal._sub._ipp._tcp"
+ DNS-SD: HP LaserJet M16a (435CA7) (USB): publishing requested
DNS-SD: HP LaserJet M16a (435CA7) (USB): AVAHI_ENTRY_GROUP_REGISTERING
DNS-SD: HP LaserJet M16a (435CA7) (USB): AVAHI_ENTRY_GROUP_ESTABLISHED
DNS-SD: HP LaserJet M16a (435CA7) (USB): published
auth: operation requested: print (HTTP POST /ipp/print)
auth: address check:
client-addr ::1 local=true
server-addr ::1 local=true
auth: client UID=-1 (auth rules don't use UID)
auth: UID -1 resolved:
user names: *
group names: *
auth: allowed operations: config,fax,print,scan
auth: access granted
> HTTP[002]: POST http://localhost:60000/ipp/print
> HTTP[002]: request body: got 173 bytes; EOF
> HTTP[002]: body is small (173 bytes), prefetched before sending
USB[2]: connection allocated, 1 in use: --- --- a--
HTTP[002]: connection 2 allocated
USB[2]: zero-size read
...(此处省略大量 zero-size read)
< HTTP[002]: POST http://localhost:60000/ipp/print - 200 OK
USB[2]: zero-size read
...(此处省略大量 zero-size read)
< HTTP[002]: response body: got 45675 bytes; EOF
USB[2]: connection released, 0 in use: --- --- ---
< HTTP[002]: done with response body
auth: operation requested: config (HTTP GET /ipp/strings/en-us)
auth: address check:
client-addr ::1 local=true
server-addr ::1 local=true
auth: client UID=-1 (auth rules don't use UID)
auth: UID -1 resolved:
user names: *
group names: *
auth: allowed operations: config,fax,print,scan
auth: access granted
> HTTP[003]: GET http://localhost:60000/ipp/strings/en-us
> HTTP[003]: body is empty, sending as is
USB[0]: connection allocated, 1 in use: a-- --- ---
HTTP[003]: connection 0 allocated
> HTTP[003]: request body: got 0 bytes; EOF
USB[0]: zero-size read
...(此处省略大量 zero-size read)
< HTTP[003]: GET http://localhost:60000/ipp/strings/en-us - 200 OK
< HTTP[003]: response body: got 197 bytes; EOF
USB[0]: connection released, 0 in use: --- --- ---
< HTTP[003]: done with response body
这段输出信息量很大。在LLM的帮助下,发现其关键内容如下:
- 设备识别 :
+ Found new device. VID:PID = 03f0:be2a,打印机被正确识别,序列号为VN50B02739,基本能力为print,http。 - USB 接口协议 :三个被标记为
*的接口全部是Class 7, SubClass 1, Protocol 4------这正是 IPP over USB 的标志。如果打印机使用传统 USB 批量传输,Protocol 应该是 1 或 2。 - IPP 服务地址 :
ipp-usb在localhost:60000上监听,提供/ipp/print端点。 - 通信验证 :可以看到三次 HTTP 请求均返回
200 OK------POST 到/ipp/print发送了打印数据,GET 到/ipp/strings/en-us获取了打印机描述信息,数据通道完全畅通。 - 扫描功能 :GET 到
/eSCL/ScannerCapabilities返回了404 Not Found,说明 M14-M17 不支持 eSCL 扫描(与 TXT 记录中的Scan=F一致)。 - DNS-SD 广播 :
ipp-usb通过 Avahi 发布了 DNS-SD 服务,其中 TXT 记录包含了打印机的完整能力信息。特别注意Duplex=F,确认该型号硬件不支持双面打印。另外可以看到打印机的内部型号标识为HP LaserJet M16a(M14-M17 系列的子型号)。 - 认证机制 :
ipp-usb对来自localhost(::1)的请求自动放行,允许config,fax,print,scan操作。
问题的根本原因已经明确:KDE 桌面在首次添加打印机时,CUPS 自动选择了 HPLIP 的 USB 后端(设备 URI 为 hp:/usb/HP_LaserJet_M14-M17?serial=...),而该打印机需要通过 ipp-usb 提供的 IPP 通道进行通信。
根据LLM分析,我按以下步骤操作:
- 让 systemd 重新接管
ipp-usb:
bash
systemctl start ipp-usb
- 删除之前通过 HPLIP 创建的错误打印队列:
bash
sudo lpadmin -x HP_LaserJet_M14-M17
- 使用
ipp-usb提供的 IPP 地址重新添加打印机,并指定everywhere驱动:
bash
sudo lpadmin -p HP_LaserJet_M14-M17 \
-v "ipp://localhost:60000/ipp/print" \
-E \
-m everywhere
-E参数表示立即启用打印机并接受打印任务。-m everywhere指定使用 CUPS 内置的 IPP Everywhere 驱动,它会通过 IPP 协议自动向打印机查询支持的能力(纸张尺寸、分辨率、PDL 等),无需手动安装 PPD 文件。这与 HPLIP 需要预置 PPD 的方式形成了鲜明对比。
- 发送测试页验证:
bash
echo "Hello from ipp-usb!" | lp -d HP_LaserJet_M14-M17
打印机成功出纸,问题解决了......一半。还有双面打印呢?
事实上,打印选项中缺失双面打印并非配置问题。通过 ipp-usb debug 输出的 DNS-SD TXT 记录可以确认 Duplex=F,即 HP LaserJet M14-M17 不具备自动双面打印单元。在 Windows 上,其是通过软件层面分两次打印奇数页和偶数页,结合手动翻面完成的。
细细一想,还有一个最大的问题。为什么 HPLIP 的 USB 后端不适配自家的打印机?
原来,在 USB 规范中,打印机接口属于 Class 7(打印设备),但协议编号区分了两种完全不同的通信方式:
| 协议编号 | 名称 | 通信方式 | 代表打印机 |
|---|---|---|---|
| Protocol 1 / 2 | 传统 USB 批量传输 | CUPS → usblp 或 HPLIP → USB bulk 端点 → 打印机 | 早期 HP LaserJet(如 P1102、M1132) |
| Protocol 4 | IPP over USB | CUPS → IPP 协议 → ipp-usb 守护进程 → USB → 打印机 | HP LaserJet M14-M17 等 IPP Everywhere 打印机 |
在 ipp-usb debug 的输出中可以明确看到 M14-M17 的 USB 接口全部使用 Protocol 4:
USB interfaces:
Config Interface Alt Class SubClass Proto
1 0 0 7 1 2
1 1 0 255 4 1
* 1 1 1 7 1 4 ← IPP over USB
1 2 0 255 4 1
* 1 2 1 7 1 4 ← IPP over USB
1 3 0 255 4 1
* 1 3 1 7 1 4 ← IPP over USB
HPLIP 的 USB 后端基于 IEEE-1284.4 协议(对应 USB 接口的 Protocol 1/2/3),通过 libusb 直接向 USB bulk 端点发送原始打印数据(PCL/PWG 光栅),绕过了 IPP 协议层。这对传统打印机没有问题,但 M14-M17 使用的是 Protocol 4(IPP over USB),期望收到的是标准 IPP 请求。当它收到一堆裸数据时,只能闪烁两下指示灯表示"收到了,但看不懂",然后丢弃。
HP 选择新打印机采用 IPP over USB 协议的原因在于,这是整个打印行业的趋势。传统模式下每家厂商都有自己的 USB 通信协议和专有驱动,导致 Linux 用户经常遇到新打印机无法使用的问题。为解决这一痛点,业界推出了 IPP Everywhere 标准------打印机像一台网络服务器一样,通过标准 HTTP/IPP 协议对外提供服务,任何支持 IPP 的客户端都可以直接使用,无需专有驱动。HP 作为该标准的推动者之一,从 2020 年前后开始在新打印机上逐步采用这一方案。
那么 HPLIP 为什么没有跟进适配呢?事实上 HPLIP 团队早在 2020 年发布的 3.20.11 版本中就已经注意到了 IPP 打印机的存在,但将其标注为 Known issues("hp-toolbox will not work for ippusbxd printers"),而非着手适配。此后直到 2025 年 11 月发布的最新版本 3.25.8,HPLIP 的更新内容始终只包含新增打印机型号的 PPD 文件和发行版兼容性,从未对 USB 后端进行架构性升级以支持 IPP over USB 协议。OpenPrinting 维护的 hplip-printer-app 项目在文档中也明确确认了这一点:HPLIP 的 USB 后端至今仍使用 IEEE-1284.4 协议。
HPLIP 自带了一个 HPLIP.conf 配置文件,会将所有 HP 设备加入黑名单,从而阻止 ipp-usb 访问这些设备。这意味着 HPLIP 不仅没有适配 IPP over USB,还在主动排斥 ipp-usb 的工作。所幸,多数 Linux 发行版在打包时会移除该配置文件。从发行版仓库安装的 HPLIP 通常不受此影响。
这个过渡期对 Linux 用户来说体验并不平滑:CUPS 和 KDE 的自动发现机制仍然会优先匹配 HPLIP 驱动,导致用户在不知情的情况下走了弯路。如果你的打印机也是较新的 HP 型号且遇到了类似的"打印完成但无反应"问题,建议优先检查 ipp-usb 的运行状态以及 CUPS 打印队列所使用的设备 URI 是否指向了正确的 IPP 端点。