环境
- 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,打印机毫无动静,没有任何报错。
根因(两个叠加,且失败被静默吞掉):
epson-escpr-wrapper 内部 popen() 硬编码调用 /usr/lib/cups/filter/epson-escpr,
但应用把过滤器装在 $PREFIX/lib/cups/filter/ 下,/usr/lib/cups/filter/ 不存在 → sh: not found;
- 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_Series 与 L850%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)一切正常,
问题只暴露给远程客户端:
<Limit CUPS-Get-Printers>、<Limit Get-Printer-Attributes>、<Limit Get-Jobs>
三个块只有 Order allow,deny 没有任何 Allow → 远程全拒
(注释写着 "open (no auth needed)",实际语义相反);
<Limit Send-Document ...> 和 <Limit All> 只 Allow localhost →
iPhone Create-Job 成功但 Send-Document 返回 401,任务永远收不到文档内容;
access_log 可见 401 ... Send-Document;
- 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/照片纸/无边)均可正常打印。需要更多日志或复测可以提供。
环境
/vol1/@appcenter/cups-web,数据目录/vol1/@appdata/cups-websudo bash scripts/bootstrap-system.sh(cupsp integrate 返回 ok)全新安装后从 web 界面、Mac、iPhone 打印全部失败。逐层排查后定位到 6 个独立问题,
全部修复并验证通过。按严重程度排列如下。
问题 1:escpr v1 打印任务全部 0 字节"假成功"(最严重)
现象:USB 打印机任务显示"已完成",page_log 记录
total 0,打印机毫无动静,没有任何报错。根因(两个叠加,且失败被静默吞掉):
epson-escpr-wrapper内部popen()硬编码调用/usr/lib/cups/filter/epson-escpr,但应用把过滤器装在
$PREFIX/lib/cups/filter/下,/usr/lib/cups/filter/不存在 →sh: not found;另外
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。修复(已验证):
修复后 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:EPSON_L850_Series与L850%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 立即生效:
建议:检查 cupsp integrate 的 udev 步骤为何跳过该规则、verify 为何误报 ok。
问题 4:生成的 cupsd.conf 拒绝远程客户端关键操作(疑似 #94 #90 的根因)
现象:Mac/iPhone 能通过 Bonjour 发现共享打印机,但连接报"无法与打印机通信";
iPhone 打印时先卡住,后弹"没有打印权限"要求输密码。
根因:cupsd 对 localhost 连接跳过全部访问检查,所以应用自身(走 socket)一切正常,
问题只暴露给远程客户端:
<Limit CUPS-Get-Printers>、<Limit Get-Printer-Attributes>、<Limit Get-Jobs>三个块只有
Order allow,deny没有任何 Allow → 远程全拒(注释写着 "open (no auth needed)",实际语义相反);
<Limit Send-Document ...>和<Limit All>只Allow localhost→iPhone
Create-Job成功但Send-Document返回 401,任务永远收不到文档内容;access_log 可见
401 ... Send-Document;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:
修复后 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/.../filterpopenepson-escpr2。修复(已验证):
建议:安装 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;
驱动安装失败: exit status 1(未深查);以上全部在真机(fnOS + L850 USB + L8180 网络)验证:6 项修复后,web 界面、Mac(IPP 共享)、
iPhone(AirPrint,含 A4/照片纸/无边)均可正常打印。需要更多日志或复测可以提供。