尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
CUPS 2.3.3源码编译与lpadmin队列排错
简介CUPS 2.3.3 源码包面向类 Unix 系统的开发者、系统管理员与打印服务学习者适合在本地部署、定制或研究开源打印系统涵盖打印作业管理、过滤器驱动、网页管理界面、加密传输与跨平台兼容等核心能力。压缩包共 1294 个文件、约 7.76MB以 C 与 C 源码、头文件、网页文档、测试脚本、模板和构建文件为主并含配置脚本、手册、打印描述示例、国际化文件及多种后端与过滤器资源目录覆盖服务端、库、工具链、策略和文档等模块。已有 928 人学习下载。完整源码结构便于读者在本地编译定制也可据此理解网络打印协议支持研究自定义过滤器与后端扩展方式或排查打印队列、驱动适配与配置管理问题对中高级运维与开发人员查漏补缺、二次开发均有参考价值。1. 从发行版包换成 cups-2.3.3-source.tar.gz一次「全都对就是打不出来」在一台要接三台网络打印机的机器上我遇到过很别扭的情况发行版仓库里装的打印服务能把队列建起来管理页面也能打开可一提交任务就卡在Filter failed日志翻半天只有一行看不出所以然的话。后来我把 cups-2.3.3-source.tar.gz 解开自己编问题没有立刻消失但至少每一步都在自己手里依赖装没装、运行目录权限对不对、过滤器在哪个目录、服务单元是谁写的全都能翻到。源码装 CUPS 最难的地方在于「编译成功」和「打印成功」是两件事——configure和make install一路绿灯只证明调度器能起来不证明你的纸能出来。2. 编译前清点工具链、依赖库与 lp 用户组的分配动手之前先花十分钟确认环境比编译完再回头补依赖省事得多。CUPS 2.3.3 属于 2.3 分支的收尾版本代码不算新对编译器要求不高但它对「系统里有没有 lp 用户」「/run 下有没有对应目录」这类事情的假设很强缺一样就在运行时报怪错。2.1 编译器与构建工具的最低要求CUPS 2.3.3 的代码大量使用 C99 特性gcc 4.8 以上、clang 3.4 以上都能编。make 需要 3.8 以上主要是为了让并行构建和install目标行为正常。另外记得装pkg-configconfigure 探测依赖库时靠它拿编译参数缺了不会直接报错但会静默判定「某个库不存在」最后你编出来的东西少一块功能。# 三行确认构建工具是否能满足 2.3.3 的最低要求 gcc --version | head -n1 # 期望 4.8 以上 make --version | head -n1 # 期望 3.8 以上 pkg-config --version # 期望 0.20 以上如果机器上同时装了多个 gcc别让 configure 抓到老的那个。我一般显式指定CC/usr/bin/gcc并在后面看config.log里实际用的是不是同一个。另外源码包里是带了configure的发布包不需要再跑autoreconf或autoconf。很多人习惯性先autoreconf -fi结果因为本机 autoconf 版本太新生成的脚本跟源码里的 m4 宏对不上直接在第一关失败。提示编译时不要往CFLAGS里加-Werror。CUPS 2.3.3 的代码在新版编译器下会产生不少新告警-Werror会把告警变成错误编到一半中断。2.2 依赖库清单必装、可选、能砍掉CUPS 的依赖分三层调度器自己需要的、过滤器需要的、外部功能需要的。先把这张表过一遍再决定装什么能少装一半东西。依赖对应功能不装的后果能否关掉zlib压缩、PPD 与 IPP 数据处理configure 直接报错退出不能libpng / libjpeg图像相关的内建转换configure 输出里这两项显示 no图像类任务受影响能但建议装openssl 开发头文件连接加密、摘要计算探测不到就退回明文基本打印不受影响能avahi / libavahi-client网段内自动发现打印机广播发现功能不可用手动加队列不受影响能加--with-dnssdnolibusbUSB 直连打印机USB 后端不可用网络打印机不受影响能cups-filtersPDF/PS 转设备格式的过滤器队列能建一打就Filter failed不能但它是独立包表格里最后一行是最容易忽略的从很早的版本开始CUPS 就把大部分过滤器拆到了独立项目里源码包装完之后/usr/lib/cups/filter下只有寥寥几个文件。你如果只用高端网络打印机自带的 IPP 处理能力问题不大一旦要驱动一台只懂 PCL 的老设备就必须另装过滤器包否则调度器会把任务接下来然后在中途找不到转换程序报一句非常笼统的错误。图像库里libpng和libjpeg这两个不用纠结装就完了。有些最小化系统只有运行时库没有开发头文件pkg-config --exists libpng返回 falseconfigure 就把这一项判成 no。装的时候记得带-devel或-dev后缀的包名。至于 avahi如果你的机器在机房里、打印机 IP 固定、队列全部手工建那就直接关掉。它带来的是一整条依赖链编译时间翻倍还容易在启动时因为守护进程没起而卡一下。我一般的写法是--with-dnssdno。2.3 用户组与安装前缀的提前规划CUPS 运行时要有两个身份一个非特权用户跑过滤器默认lp一个管理组决定谁能通过本地套接字做管理操作默认lpadmin。这两个东西不搞好后面lpadmin建队列会莫名其妙地提示认证失败。# 确认 lp 用户和 lpadmin 组是否存在缺了就补 getent passwd lp || useradd -r -s /sbin/nologin -d /var/spool/lpd lp getent group lpadmin || groupadd -r lpadmin # 把日常运维账号加进 lpadmin避免每次都用 root 做管理操作 usermod -aG lpadmin opsusermod之后要重新登录才生效别在这个 shell 里接着测会以为加组失败。管理组的作用是配置文件里写SYSTEM的地方实际展开就是这个组。Web 管理页要求输入账号密码时走的也是这套逻辑。安装前缀也要提前定。我固定用--prefix/usr、--sysconfdir/etc、--localstatedir/var。为什么不装/usr/local因为 CUPS 的部分组件有自己写死的默认路径查找逻辑装到/usr/local后 man 页、服务单元、以及某些按/usr/lib/cups硬编码的第三方脚本会对不上出问题时排查成本远大于省下的那点隔离收益。如果你的系统是 64 位且库目录分了 lib 和 lib64还要额外加--libdir/usr/lib64否则后端和过滤器会落到/usr/lib/cups而某些按 lib64 找东西的组件找不到它们表现就是「队列正常打印无声失败」。3. configure 到 make installCUPS 2.3.3 的参数逐条拆这一章是整个安装过程里最需要看清楚的一段。参数写错几个编译照样成功问题留到运行时才暴露那时候你就得靠日志猜了。3.1 解包与源码树自检# 先看包内结构确认是一级目录还是裸文件 tar -tzf cups-2.3.3-source.tar.gz | head -n 5 # 解开并进入源码目录 tar -xzf cups-2.3.3-source.tar.gz cd cups-2.3.3 # 发布包一定带这两个文件缺一个就说明拿到的不是发布包 ls -l configure INSTALLconfigure文件存在且可执行说明这是打包好的发布版本直接跑就行。如果只有configure.ac和configure.in那是开发树得先autoconf编译门槛和踩坑概率都会上一个台阶能换发布包就换。解包之后顺手看一眼CHANGES.txt里 2.3.3 这一节的修复条目能提前知道这个版本改过哪些路径相关的行为。长期维护的机器这一步值得做。3.2 configure 参数取舍这是我在这类环境里用得最多的一套组合./configure \ --prefix/usr \ --sysconfdir/etc \ --localstatedir/var \ --libdir/usr/lib64 \ --with-rundir/run/cups \ --with-system-groupslpadmin \ --with-printcap/etc/printcap \ --with-dnssdno \ --enable-shared \ --disable-static \ CFLAGS-O2 -g CXXFLAGS-O2 -g每个参数的理由--prefix/usr二进制落在/usr/sbin和系统里已有的工具路径一致PATH 不用改。--sysconfdir/etc配置文件最终进/etc/cups这是 CUPS 自己也在找的位置。--localstatedir/varspool 在/var/spool/cups日志在/var/log/cups缓存进/var/cache/cups。--libdir/usr/lib64决定后端、过滤器、通知器的安装位置。64 位系统上不写这个容易和按 lib64 找文件的组件错位。--with-rundir/run/cupsPID 文件、本地域套接字都在这里。用/run而不是/var/run是因为现在多数系统/var/run只是软链写死旧路径在某些场景下会失效。--with-system-groupslpadmin决定SYSTEM展开成哪个组直接影响谁能管理队列。--with-printcap/etc/printcap有些老脚本和老工具还在读这个文件留着能省事。--with-dnssdno关掉网段广播发现砍掉 avahi 依赖链。--enable-shared --disable-static只编动态库省体积也省编译时间。静态库在这类场景里没有使用价值。CFLAGS-O2 -g保留调试符号是为了将来真出问题时能用调试器看栈。生产机器上多几十兆磁盘换一个可排查的现场我觉得划算。跑完 configure别急着 make把输出末尾那段构建配置摘要存下来# 把 configure 的关键探测结果留下来将来对比版本差异时非常有用 ./configure ... 21 | tee /tmp/cups-configure.log grep -iE png|jpeg|openssl|avahi|dnssd|pam|usb /tmp/cups-configure.log摘要里如果某项显示 no 而你以为装了回去翻config.log搜索checking for对应的那一行能看到具体的编译或链接失败原因。这一步是后面所有排查的基础我习惯把这个日志留在机器上命名里带日期。3.3 make 并发与安装后的目录核验# 并行编译日志留一份编译告警不要忽略 make -j$(nproc) 21 | tee /tmp/cups-build.log # 安装注意这一步会往 /etc、/usr、/var 下写文件 make installmake -j的并发数按 CPU 核数给就行CUPS 的构建脚本没有并行依赖问题但把日志 tee 出来很重要。CUPS 编译过程中的告警里有一类是「某个可选组件未找到跳过」这类信息不会让编译失败但直接决定你装完以后功能是否完整。安装完成后按下面的清单核验一遍# 主程序是否就位、版本是否是 2.3.3 ls -l /usr/sbin/cupsd /usr/sbin/cupsd -v # 三个关键目录是否都有内容 ls /usr/lib64/cups/backend ls /usr/lib64/cups/filter ls /usr/lib64/cups/notifier # 配置目录下应该是 cupsd.conf、cups-files.conf 和对应的 .default ls -l /etc/cups # 检查 cupsd 链接了哪些外部库确认没有意外的缺库 ldd /usr/sbin/cupsd | grep -i not found关于/etc/cups有一点要提前知道make install遇到已存在的配置文件时不会直接覆盖新的那份会以.default结尾留下来。如果你是从旧版本升级或之前装过发行版包cupsd.conf很可能还是旧内容。第一次装可以不管但只要机器上原本就有配置就得手动对比一次否则你会以为参数生效了实际跑的还是一年前的配置。/usr/lib64/cups/filter目录里如果只有三四个文件不要慌这是正常的剩下的大量过滤器在独立的过滤器包里。这一点在第五章的排错里会详细说。4. 配置与接管cupsd.conf、自写 systemd 单元与第一个打印队列编译安装和「服务能自动拉起」之间还差好几步。源码包不会替你装服务单元也不会替你建运行目录更不会替你写好配置文件里那些必须显式声明的授权段落。这一章做完才算把这套东西接管过来。4.1 运行目录与权限cupsd 启动前必须存在的三处cupsd 启动时会检查几个目录缺了会自己建但权限不对时它会拒绝服务报出来的话通常很含糊只说某个目录不安全。手工先建好能少走一段弯路。# 运行目录放 PID 和本地套接字属主 root属组 lp0755 install -d -m 0755 -o root -g lp /run/cups # spool 目录放待打印任务权限必须收紧到 0710 install -d -m 0710 -o root -g lp /var/spool/cups # 日志与缓存目录 install -d -m 0755 -o root -g lp /var/log/cups install -d -m 0755 -o root -g lp /var/cache/cups/var/spool/cups的0710不是随手写的。打印任务里可能包含敏感文档这个目录如果对其他用户可读cupsd 启动时会打印一条警告某些编译选项下直接拒绝启动。0755是常见误填一定要改。/run目录还有个额外问题它基于内存文件系统重启就清空。所以要么用 systemd 的RuntimeDirectory要么写一条tmpfiles.d规则。我倾向后者因为调试时手动起停更可控# /etc/tmpfiles.d/cups.conf d /run/cups 0755 root lp -这条规则的意思是目录不存在就创建权限 0755属主 root属组 lp。tmpfiles在开机早期运行比服务启动早顺序上刚好。4.2 cupsd.conf 最小可用配置配置文件分两个cupsd.conf放服务行为cups-files.conf放路径和身份。这两者分开是有原因的从 1.6 之后User、Group、SystemGroup、ServerBin这类涉及文件系统访问的指令全部搬到了cups-files.conf写回cupsd.conf不会生效某些版本还会直接报「未知指令」。这是很典型的一个坑。先看cups-files.conf里要确认的几行# /etc/cups/cups-files.conf # 过滤器运行身份必须是一个真实存在的非特权用户 User lp Group lp # 管理组对应 SYSTEM 的展开结果 SystemGroup lpadmin # 本地域套接字位置lpadmin 通过它做认证 DomainSocket /run/cups/cups.sock再看cupsd.conf的最小可用版本# /etc/cups/cupsd.conf # 日志级别排查期用 debug2稳定后改回 warn LogLevel warn MaxLogSize 0 # 只监听本机和内网本地套接字必开 Listen localhost:631 Listen /run/cups/cups.sock # 允许 Web 管理页 WebInterface Yes # 默认认证方式 DefaultAuthType Basic Location / Order allow,deny Allow localhost Allow 192.168.10.0/24 /Location Location /admin Order allow,deny Allow localhost Allow 192.168.10.0/24 /Location Location /admin/conf AuthType Default Require user SYSTEM Order allow,deny Allow localhost /Location几个要点Listen localhost:631和Listen /run/cups/cups.sock这两行是并列关系前者给 Web 页面和远程 IPP 用后者给本机的lpadmin、lpstat等命令用。少写第二行命令行工具会去连默认套接字然后失败报的错是「无法连接到服务器」很容易被误判成服务没起。192.168.10.0/24换成你自己网段。这个网段只是示例实际要比你这台机器能访问的打印机的网段匹配。Location /admin/conf里加了Require user SYSTEM意思是只有管理组的人能改配置其他授权网段的人只能看队列和提交任务。这个分层的意义在于Web 界面谁都能打开但改配置需要身份。配置写完先做语法检查别急着启动# 只检查配置语法不真正启动服务 /usr/sbin/cupsd -t # 想看更细的解析过程加 -c 指定配置文件再配合 -t /usr/sbin/cupsd -t -c /etc/cups/cupsd.conf-t的返回值是 0 才继续非 0 就去/var/log/cups/error_log看最后几行通常会明确指出行号。4.3 自写 systemd 单元让服务开机自起源码安装不会给你装服务单元。自己写一份放在/etc/systemd/system下比改源码树里的模板更清楚来龙去脉。# /etc/systemd/system/cups.service [Unit] DescriptionCUPS Scheduler Afternetwork.target Wantsnetwork.target [Service] Typesimple # -f 表示前台运行交给 systemd 托管进程 ExecStart/usr/sbin/cupsd -f # 让 systemd 管理 /run/cups重启后自动重建 RuntimeDirectorycups RuntimeDirectoryMode0755 Restarton-failure RestartSec5s LimitNOFILE65536 [Install] WantedBymulti-user.targetTypesimple配-f是最省心的组合cupsd 在前台跑标准输出和错误都进 journalsystemctl status能直接看到。不要用Typeforking那样进程一退出父进程日志归属就乱了排查时体验很差。RuntimeDirectorycups会让 systemd 在启动前建好/run/cups并在停止后清理和前面写的 tmpfiles 规则功能重叠但不冲突。两处都留着是为了在手动cupsd -f调试时目录也在。启用并启动systemctl daemon-reload systemctl enable --now cups # 三件事一起看服务状态、端口监听、启动日志 systemctl status cups --no-pager ss -ltnp | grep 631 journalctl -u cups -n 30 --no-pager如果 631 端口没起来而服务显示 active多半是配置文件里的Listen段落写错或者端口被上一次没退干净的进程占着。ss -ltnp的输出里能看到占用者的 PID直接处理。4.4 用 lpadmin 建第一个队列服务起来之后先看看这台机器能识别到哪些设备# 列出所有可用的后端和设备 URI lpinfo -v输出里通常会有network ipp、network socket、direct usb这几类。网络打印机优先用 IPP直接写设备的 IPP 地址# 建一个走 IPP Everywhere 的队列由服务端自动协商能力 lpadmin -p office-a \ -E \ -v ipp://192.168.10.20/ipp/print \ -m everywhere \ -D Office A \ -L 3F \ -o printer-is-sharedfalse # 设为默认队列 lpadmin -d office-a参数拆开说-p是队列名只能用字母数字和连字符-E表示建完立刻启用并接受任务漏了它队列是禁用状态lpstat -t里会显示disabled-v是设备 URI-m everywhere让调度器跟设备协商生成 PPD不需要你预先准备驱动文件-D和-L是描述和位置人多的时候很有用-o printer-is-sharedfalse表示不通过广播共享出去。如果设备比较老、只认 9100 端口的原始数据流可以用 raw 队列跳过格式转换# 老设备兜底方案不打任何过滤直接把字节流送过去 lpadmin -p legacy-1 -E -v socket://192.168.10.31:9100 -m rawraw 队列的好处是不依赖过滤器坏处是格式转换全交给客户端。两种方式按设备情况选不要为了统一全用 raw那样 PDF 直接被推给打印机出来一堆乱码。5. 排查清单cupsd 起不来和打不出纸的五个现场这一章是我自己攒的问题记录。CUPS 的日志写得不算差但很多错误信息是「结果」不是「原因」得顺着往下摸。下面五条按现象、原因、解决的顺序写遇到对应症状可以直接对照。5.1 服务起不来的三个现场现象一systemctl start cups失败日志只有一行Unable to open Listen socket - Address already in use。原因上一次的 cupsd 没退干净或者系统里还有另一个打印服务单元在抢 631 端口。RPM 或 deb 包安装的版本和自己编的版本共存时特别容易出现两个单元名字不同但都监听同一端口。解决ss -ltnp | grep 631找到占用的 PID先确认是不是打印相关进程是就kill掉再systemctl disable掉不用的那个单元。别直接pkill cupsd完事端口释放有延迟隔一两秒再启动。现象二服务启动后立刻退出journalctl里只有cupsd: Child exited with status 1没有任何具体原因。原因cupsd 在守护化之前把真正的错误写到了标准错误但被 systemd 吞掉了或者配置里的LogLevel设得太高关键信息被过滤。另一个常见原因是cups-files.conf里User指定的用户不存在cupsd 在降权那一步失败后静默退出。解决手动前台跑一遍直接看输出# 前台运行标准错误直接打到终端最能暴露真实原因 /usr/sbin/cupsd -f -c /etc/cups/cupsd.conf顺手确认一下getent passwd lp有输出。这个「守护进程起不来就前台跑一遍」的习惯帮我省过太多次瞎猜。现象三服务起来了631 端口也在听但lpstat -t报Unable to connect to server。原因本地域套接字没建出来或者建在别的位置。cups-files.conf里的DomainSocket和cupsd.conf里的Listen没对齐时就会这样客户端按编译时的默认路径找套接字服务端在另一个路径上监听。解决ls -l /run/cups/cups.sock看文件在不在。不在的话检查两处路径是否一致改完重启。顺手看一眼semanage或强制访问控制的审计日志某些默认开启强制访问控制的系统上套接字会被策略挡住表现同样是「本文还有配套的精品资源点击获取
RELATED

相关推荐

MATLAB 16QAM星座图与误码率仿真:链路实现与避坑

MATLAB 16QAM星座图与误码率仿真:链路实现与避坑

简介:面向通信原理与数字调制课程学习者的16QAM仿真代码包,聚焦星座图绘制与误码率评估两个核心实验环节,适合需要理解QAM映射、解调判决与AWGN信道性能的本科生或自学者动手复现。包内共8个文件,均为MATLAB的.m脚本与函数&#x…

📅 2026/10/23 17:58:00
Matlab弹道计算程序解析:ODE45求解与阻力/科氏力建模

Matlab弹道计算程序解析:ODE45求解与阻力/科氏力建模

简介:这是一份面向航空航天、兵器工程与力学相关专业学生的Matlab弹道计算程序资料,用于解决外弹道仿真中的质点弹道建模与数值求解问题。压缩包共1个docx文档,大小约72KB,文档内含完整Matlab代码、模型推导说明、符号约定与算例数…

📅 2026/10/23 17:52:58
Java17 Switch表达式与模式匹配:从控制流重构到编译期安全

Java17 Switch表达式与模式匹配:从控制流重构到编译期安全

1. 这不是“语法糖”,是Java控制流的底层重构你可能已经看到过类似“Java17 Switch终于支持返回值了”这样的标题,但如果你真这么理解,就错过了这次演进最本质的变革。我带团队在某跨平台系统升级中落地Java17时,最初也以为只是加…

📅 2026/10/23 17:52:58
MORE NEWS

更多资讯

📰

极限资源榨取:从2GB内存边缘设备看未来端侧智能的算力民主化

在动辄配备 8 张 H100 GPU、整机显存高达 640GB 的云端数据中心里,算法工程师们习惯了挥霍显存与算力。然而,工业网关、智能车载 T-Box、路侧边缘感知单元以及数以亿计的存量嵌入式设备,面对的物理现实往往残酷得多:只有一颗 4 核…

📰

SAP采购价格确定原理与四要素解析

简介:本资源是一份面向SAP采购模块初学者与实施顾问的系统性学习文档,聚焦采购价格确定这一核心业务场景,深入解析条件技术在实际配置中的落地逻辑。内容覆盖条件类型(PB00/PB01/PB02)、存取顺序、条件记录与条件表、计…

📰

PHPCMS V9 UTF8架构解析:从路由、内容模型到模板标签与二次开发实战

简介:PHPCMS V9 UTF8 是一套基于 PHP 与 MySQL 的开源内容管理系统,适配多语言、UTF-8 编码站点建设,主要面向需要搭建企业官网、资讯门户或电商平台的开发者、站长及运维人员。系统内置文章发布、分类管理、自定义模型、评论管理、模板引擎、…

📰

复变函数期末复习:掌握解析判断与留数定理,攻克高频考点

简介:这份复变函数期末复习资料面向数学相关专业及工科学生,以五章核心知识为主线,系统梳理复数基本概念、解析函数与柯西-黎曼方程、复积分、幂级数展开和留数理论,并针对期末高频题型整理典型例题与解题步骤。资料为docx文档&am…

📰

信号分析与处理实验:Matlab波形到频域分析的完整实操记录

简介:这份资源是南京邮电大学「信号分析与处理实验」课程的完整实验报告,面向正在修读数字信号处理、信号与系统相关课程的高校学生,以及需要借助 MATLAB 完成信号处理实验与课程设计的自学者。报告围绕信号的产生和运算、连续时间信号的频域…

📰

MATLAB/Simulink通信系统建模:BPSK与QPSK在AWGN信道下的误码率对比

简介:这份课程设计资源面向通信工程、电子信息类专业学生及需要完成MATLAB/Simulink仿真实训的学习者,围绕AWGN信道下BPSK与QPSK调制方式展开对比研究。内容从两种调制解调原理入手,涵盖需求分析、设计思路、Simulink模型搭建、不同信噪比下的…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬