Skip to content

[fnOS 原生版] 全新安装无法打印的 6 个根因定位(含修复验证,或可解释 #94 #90 #82) #100

Description

@liangbingjia

环境

  • fnOS(飞牛OS)原生 FPK 安装,非 Docker
  • cups-web 应用目录 /vol1/@appcenter/cups-web,数据目录 /vol1/@appdata/cups-web
  • 打印机:EPSON L850(USB 直连,escpr v1 驱动)、EPSON L8180(网络,escpr2 驱动)
  • 已执行 sudo bash scripts/bootstrap-system.sh(cupsp integrate 返回 ok)

全新安装后从 web 界面、Mac、iPhone 打印全部失败。逐层排查后定位到 6 个独立问题,
全部修复并验证通过。按严重程度排列如下。


问题 1:escpr v1 打印任务全部 0 字节"假成功"(最严重)

现象:USB 打印机任务显示"已完成",page_log 记录 total 0,打印机毫无动静,没有任何报错。

根因(两个叠加,且失败被静默吞掉):

  1. epson-escpr-wrapper 内部 popen() 硬编码调用 /usr/lib/cups/filter/epson-escpr,
    但应用把过滤器装在 $PREFIX/lib/cups/filter/ 下,/usr/lib/cups/filter/ 不存在 → sh: not found;
  2. wrapper 不检查 popen 子进程退出码,照常返回 0 → CUPS 认为任务成功,发给 backend 的数据是 0 字节。

另外 install-escpr.sh 是源码编译方案,fnOS 上没有工具链,libescpr.so.1 实际从未装上
(ldd $PREFIX/lib/cups/filter/epson-escpr 显示 libescpr.so.1 => not found),
即使路径通了也会以同样方式静默失败。

验证过程:手动重放过滤链,imagetoraster 正常产出 28MB 光栅,epson-escpr-wrapper
输出 0 字节且 stderr 有 sh: 1: /usr/lib/cups/filter/epson-escpr: not found,退出码却是 0。

修复(已验证):

# 1) 补库(从 Debian 二进制包提取,版本与内置 1.7.17 一致)
curl -fsSL -o /tmp/escpr.deb "https://deb.debian.org/debian/pool/main/e/epson-inkjet-printer-escpr/printer-driver-escpr_1.7.17-4_amd64.deb"
dpkg-deb -x /tmp/escpr.deb /tmp/escpr-x
cp -a /tmp/escpr-x/usr/lib/printer-driver-escpr/libescpr.so.1* $PREFIX/lib/
# 2) 补硬编码路径
sudo mkdir -p /usr/lib/cups/filter
sudo ln -sfn $PREFIX/lib/cups/filter/epson-escpr /usr/lib/cups/filter/epson-escpr

修复后 wrapper 产出 13MB 正常 EJL 数据,物理出纸成功。

建议:escpr v1 改用 Debian 预编译二进制分发(像 escpr2 一样),不要现场编译;
bootstrap 里创建 /usr/lib/cups/filter 符号链接;可能的话给 wrapper 打补丁检查 popen 返回值。


问题 2:USB 设备 URI 用下划线合成,与 backend 永远不匹配

现象:USB 队列一直 "Waiting for printer to become available",任务无限排队,
但设备发现页能看到打印机。

根因:应用添加打印机时自己合成 URI usb://EPSON/EPSON_L850_Series?serial=...
(空格→下划线,且用了 product 字符串)。而 CUPS usb backend 实际生成的 URI 来自
IEEE-1284 Device ID 的 MFG/MDL 字段,空格是 %20:

$ sudo -u cups-web $PREFIX/lib/cups/backend/usb
direct usb://EPSON/L850%20Series?serial=555458593032333017&interface=1 ...

EPSON_L850_SeriesL850%20Series 永远对不上,backend 找不到"那台"打印机。

修复(已验证):lpadmin -p <queue> -v 'usb://EPSON/L850%20Series?serial=...' 后立即恢复。

建议:添加 USB 打印机时应以 lpinfo -v / usb backend 发现模式返回的 URI 为准,不要自行拼接。


问题 3:bootstrap 宣称成功但 99-usb-printer.rules 未落盘

现象:cupsp integrate 返回 {"ok":true,...,"steps":[...,"udev",...],"verify":{"status":"ok"}},
/etc/udev/rules.d/ 里只有 HP 两条规则,99-usb-printer.rules 不存在。
结果 USB 设备节点是 root:lp 0660,而 cups-web 用户不在 lp 组,backend 无权限打开设备。

临时修复(已验证):自建规则后 udevadm trigger 立即生效:

SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTR{idVendor}=="04b8", OWNER="cups-web", GROUP="lp", MODE="0660"

建议:检查 cupsp integrate 的 udev 步骤为何跳过该规则、verify 为何误报 ok。


问题 4:生成的 cupsd.conf 拒绝远程客户端关键操作(疑似 #94 #90 的根因)

现象:Mac/iPhone 能通过 Bonjour 发现共享打印机,但连接报"无法与打印机通信";
iPhone 打印时先卡住,后弹"没有打印权限"要求输密码。

根因:cupsd 对 localhost 连接跳过全部访问检查,所以应用自身(走 socket)一切正常,
问题只暴露给远程客户端:

  1. <Limit CUPS-Get-Printers><Limit Get-Printer-Attributes><Limit Get-Jobs>
    三个块只有 Order allow,deny 没有任何 Allow → 远程全拒
    (注释写着 "open (no auth needed)",实际语义相反);
  2. <Limit Send-Document ...><Limit All>Allow localhost
    iPhone Create-Job 成功但 Send-Document 返回 401,任务永远收不到文档内容;
    access_log 可见 401 ... Send-Document;
  3. ssl 目录不存在,error_log 大量
    Unable to encrypt connection: Unable to create server credentials,
    ipps(AirPrint 默认)握手直接失败。

修复(已验证):上述块补 Allow @LOCAL,创建 $DATA/cups/etc/cups/ssl
chown cups-web,SIGHUP cupsd。修复后 Mac ipptool get-printer-attributes PASS,iPhone 正常打印。

:cupsd.conf 每次应用重启会重新生成,手工修复会被覆盖,希望模板本身修正。


问题 5:iPhone 纸张列表只有 Letter/Legal(疑似 #82 同类)

现象:AirPrint 打印时纸张只有"美国信纸/美国法定",没有 A4 和照片纸。

根因:iOS 只显示 media-ready(已装纸列表)。cupsd 未配置 ReadyPaperSizes 时按
locale 兜底为 Letter,Legal。另外 media-ready 是 PPD 加载时计算并缓存在
var/cache/*.data 的,只改配置不清缓存不生效。

修复(已验证):cupsd.conf 加一行(含 Epson 无边 T 系列),清缓存 + touch PPD + SIGHUP:

ReadyPaperSizes A4,TA4,A5,A6,B5,4X6FULL,T4X6FULL,4X7,T4X7,2L,T2L,L,TL,8x10,T8x10,INDEX5,Letter,Legal

修复后 iPhone 正常显示 A4/照片纸,含无边距变体(media-col-ready 的 0 边距条目)。

建议:生成 cupsd.conf 时根据队列 PPD 支持的尺寸自动生成 ReadyPaperSizes,或至少默认包含 A4。


问题 6:escpr2 PPD 的 cupsFilter 指向不存在的 /opt 路径

现象:escpr2 队列(L8180)报
File "/opt/epson-inkjet-printer-escpr2/cups/lib/filter/epson-escpr-wrapper2" not available

根因:install-escpr2.sh 把过滤器复制到 $PREFIX/lib/cups/filter/,但从 deb 解出的 PPD 里
*cupsFilter: 仍是 /opt/epson-inkjet-printer-escpr2/... 绝对路径,未做改写;
且 wrapper2 二进制内部也硬编码从 /opt/.../filter popen epson-escpr2

修复(已验证):

sudo mkdir -p /opt/epson-inkjet-printer-escpr2/cups/lib
sudo ln -sfn $PREFIX/lib/cups/filter /opt/epson-inkjet-printer-escpr2/cups/lib/filter

建议:安装 PPD 时把 /opt 前缀改写为相对过滤器名
(*cupsFilter: "application/vnd.cups-raster 0 epson-escpr-wrapper2",
cupsd 会在 ServerBin/filter 下解析),或由 bootstrap 建 /opt 符号链接。


附:小问题

  • 共享状态校验疑似查错对象:日志
    ListPrinters: name="EPSON_EPSON_L850_Series" uri="ipp://localhost:8631/printers/EPSON_L8180_Series"
    (name 与 uri 不是同一台),导致误报 shared printer state is partial,
    实际 printers.conf 中 Shared 已是 Yes;
  • 驱动向导里 Gutenprint 点"安装"报 驱动安装失败: exit status 1(未深查);
  • wrapper 对子进程失败不报错的问题同样存在于 wrapper2(硬编码 + 不检查返回值),建议一并处理。

以上全部在真机(fnOS + L850 USB + L8180 网络)验证:6 项修复后,web 界面、Mac(IPP 共享)、
iPhone(AirPrint,含 A4/照片纸/无边)均可正常打印。需要更多日志或复测可以提供。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions