Linux老一体机打印扫描:v1.00.06驱动部署与CUPS/SANE排障
简介SAMSUNG三星打印及扫描驱动1.00.06版面向Linux-32与Linux-64平台的用户提供官方打印、扫描支持适合在Linux桌面、开发测试或轻量办公环境中连接多型号三星打印一体机与扫描仪时使用可缓解设备识别、驱动兼容与扫描后端缺失等问题。压缩包按32位与64位平台分别组织共229个文件约10.1MB包含141个ppd型号描述文件、28个cts组件、7个sh安装脚本以及pstospl与rastertospl转换工具、smfpnetdiscovery网络发现程序、so库和conf、cfg等配置文件覆盖打印队列、扫描后端、设备发现与安装部署等环节。现有818人学习下载适合需要为旧款三星设备补齐Linux驱动、排查打印扫描链路的用户参考。包内脚本与配置文件较完整便于按具体发行版调整安装流程、核对设备型号并定位扫描失败或网络连接异常等问题也能作为理解Linux打印架构与驱动组成的学习材料。1. 一台停产一体机插上 Linux为什么还得回头找这个 v1.00.06 驱动包上周帮人收拾一台退役的激光多功能一体机USB 线插上lsusb能看到设备节点但系统打印机列表里空空如也桌面环境的自动添加弹出一句「driverless 不支持该型号」手工建队列又不知道 URI 该填什么。这时候能救场的往往就是厂商当年发布的那个 Linux 统一驱动包——版本号 v1.00.06同时提供 32 位与 64 位两套安装文件。它解决的不是「新设备怎么连」而是「老设备在没有 IPP Everywhere、没有 Mopria、也没有开源后端覆盖的情况下怎么在现行发行版上打印和扫描」。适合手上还压着这类机器、又不打算为它单独留一台 Windows 的人运维、实验室设备管理员、以及喜欢把旧硬件榨干的做法。2. 拆开安装包看清单CUPS filter、PPD 与 SANE 后端各自管什么很多人拿到这类驱动包的第一反应是双击install.sh装完打印机能出纸就以为完事扫描坏了再回头翻日志。实际上一套「打印 扫描」的统一驱动包里装的是三套完全独立的东西它们走的是两条互不相干的内核路径。搞清楚谁管谁后面出问题才能一眼定位到是打印链路还是扫描链路。2.1 三类文件的落点与调用链解开压缩包之后目录结构大同小异通常长这样# 解开统一驱动包先只看结构不解压执行 tar -tzf uld_v1.00.06.tar.gz | head -n 40 # 展开后大致是 # ./cdroot/ # ./cdroot/Linux/ # ./cdroot/Linux/i386/... # 32 位二进制 # ./cdroot/Linux/x86_64/... # 64 位二进制 # ./cdroot/Linux/noarch/... # PPD、配置、脚本 # ./install.sh # ./install-printer.sh # ./install-scanner.sh三类文件各自的职责是这样的第一类是 CUPS filter也就是真正把应用层数据翻译成打印机认识的页面描述语言的那个可执行程序。它被安装到/usr/lib/cups/filter/下面文件名通常是厂商前缀加filter或rasterto*。CUPS 在处理一个打印任务时会按 PPD 里cupsFilter字段声明的顺序依次调用这些程序前一环的输出就是后一环的输入。设备越老这个 filter 越是绕不开——因为老机器不支持 PDF 直出也不支持 IPP 里的标准光栅格式。第二类是 PPD 文件纯文本描述这台机器支持什么纸张、什么分辨率、双面怎么翻、纸盒怎么选。它被放到/usr/share/cups/model/或者厂商自己的目录里lpadmin -m建档时读的就是它。PPD 里同时写死了 filter 的绝对路径所以一旦 filter 被装到了别的地方CUPS 会在日志里报找不到。第三类是 SANE 后端一个libsane-*.so动态库加一份同名的.conf配置。它走的是完全不同的路径scanimage调libsanelibsane读/etc/sane.d/dll.conf里列出的后端名再去/usr/lib/x86_64-linux-gnu/sane/Debian 系或/usr/lib64/sane/RHEL 系加载对应的.so最后通过 libusb 直接跟设备讲话。也就是说打印走 CUPS扫描走 SANE两者只在「都要访问同一个 USB 设备节点」这一点上产生交集而这个交集正是后面权限问题的根源。提示不要假设装完打印机扫描就能用。install.sh里通常会分别调用打印机和扫描两套子脚本但子脚本失败时主脚本不一定中断装完不报错不代表装全了。2.2 装之前的依赖体检先对二进制跑 ldd再动手这类闭源二进制最常见的失败原因不是逻辑错而是缺共享库。厂商编译时的基线环境往往比你现在跑的发行版老好几年典型的坑包括libpng12很多新发行版已经推进到 libpng16、libusb-0.1-4老后端还在用 0.1 的 API、以及老版本libstdc。与其装完打印时看到一句没头没尾的Filter failed不如在解压之后、执行安装之前先把二进制挨个ldd一遍# 1. 确认当前系统的架构决定用 i386 还是 x86_64 目录 uname -m # 输出 x86_64 就走 x86_64 目录aarch64 基本可以直接放弃这个包 # 2. 找到包里所有可执行文件和动态库 find ./cdroot -type f \( -name *.so* -o -perm -ux \) -print0 \ | xargs -0 file | grep -E ELF # 3. 对 64 位那一份逐个检查动态链接 find ./cdroot/Linux/x86_64 -type f -perm -ux -print0 \ | while IFS read -r -d f; do echo $f ldd $f 2/dev/null | grep not found doneldd输出里出现not found的那一行左边就是缺失的库名直接拿去包管理器里搜同名包即可。这一步的价值在于它把「装完之后玄学般打不出来」提前变成了「装之前就知道缺哪三个库」。我一般还会顺手确认一下glibc版本因为部分厂商的 filter 会用到较新的符号版本# 检查 glibc 版本低于二进制编译基线时会报 GLIBC_2.xx not found ldd --version | head -n 1 # 如果 ldd 报的是符号版本缺失而非文件缺失用这个看得更清楚 objdump -T ./cdroot/Linux/x86_64/.../xxxfilter | grep GLIBC | sort -u | tail参数说明上-perm -ux表示「属主有执行位」用它筛出来的基本就是会被 CUPS 或 SANE 直接 exec 的文件file那一步是为了排除误筛进来的脚本。如果ldd报not a dynamic executable说明命中的是 shell 脚本跳过即可。真缺库而发行版仓库里已经没有对应老包时可行的路子是从旧版发行版的归档仓库里取出单个.deb解开把.so放到/opt/vendor/lib/下再给 filter 加一个LD_LIBRARY_PATH的包装脚本——这个做法不算优雅但对一台只需要再撑两年的老机器是划算的。3. 打印链路打通从 install.sh 到 lpadmin 出第一张测试页依赖过了关接下来是把队列建起来。这里有个取舍用桌面打印管理界面点选还是全命令行手工建。我的建议是先关掉桌面的自动发现走纯命令行因为自动发现失败时给出的错误信息几乎为零而lpadmin加error_log至少能告诉你卡在哪一步。3.1 安装脚本的两种跑法与落点确认统一驱动包一般提供三个入口install.sh一把梭、install-printer.sh只装打印、install-scanner.sh只装扫描。分步装的好处是每一步失败都能立刻看见。# 解压并进入目录 tar -xzf uld_v1.00.06.tar.gz cd uld # 只装打印部分观察输出 sudo ./install-printer.sh # 装完之后确认三件事filter 在不在、PPD 在不在、CUPS 认不认 ls -l /usr/lib/cups/filter/ | grep -i -E mfp|filter ls -l /usr/share/cups/model/ | grep -i ppd lpinfo -m | wc -l如果脚本报cupsd: unrecognized service或者尝试调用/etc/init.d/cups restart失败这在 systemd 系统上很常见属于脚本年代久远的正常现象手动重启一次即可不影响文件落点# systemd 环境下重启 CUPS 并确认状态 sudo systemctl restart cups systemctl is-active cups # 确认 PPD 已被 CUPS 扫描到-m 会重新读 model 目录 lpinfo -m | grep -i 该系列型号关键字这里的关键是lpinfo -m那一步。CUPS 会缓存 model 目录的内容PPD 拷进去之后不重启服务、不触发一次lpinfo -m新建队列时可能就选不到它。装完看不到 PPD八成不是没拷进去而是没刷新。3.2 用 lpadmin 手工建队列把 URI 和 PPD 一次钉死确认 PPD 可见之后建队列这一步反而不复杂。难点在于 URI 怎么写。USB 直连的机器URI 形式是usb://厂商/型号?serialxxx这个串可以用lpinfo -v让 CUPS 自己枚举出来# 列出 CUPS 当前能看到的全部后端设备 lpinfo -v | grep -i usb # 输出形如 # direct usb://Vendor/Model%20Series?serial0000000000 # 用枚举出来的 URI 建队列-m 直接指向 PPD 绝对路径最稳 sudo lpadmin -p MFP-01 \ -E \ -v usb://Vendor/Model%20Series?serial0000000000 \ -m /usr/share/cups/model/vendor_mfp_series.ppd \ -o printer-is-sharedfalse \ -o PageSizeA4 # 启用并接受任务新队列默认可能是 stopped 状态 sudo cupsenable MFP-01 sudo cupsaccept MFP-01 # 打一张最小测试页别用图形界面排除前端干扰 lp -d MFP-01 -o mediaA4 /etc/hostname lpstat -o MFP-01参数逐个说明-E表示建完立即启用并接受任务等价于后面两条cupsenable加cupsaccept-v是设备 URIUSB 直连用usb://网络机型用socket://IP:9100或ipp://IP/ipp/print-m既可以给 PPD 的绝对路径也可以给lpinfo -m里输出的那串模型名给绝对路径更不容易错-o printer-is-sharedfalse在只想本机用的时候关掉共享能省掉一堆 mDNS 注册带来的干扰-o PageSizeA4会写进队列默认选项比在每个应用里单独设靠谱。如果任务提交后一直停在processing或者直接消失第一件事是开 CUPS 的调试日志# 临时开 debug 级别日志量很大排查完记得关 sudo cupsctl --debug-logging sudo tail -f /var/log/cups/error_log # 复现一次打印 lp -d MFP-01 /etc/hostname # 排查结束后关掉 sudo cupsctl --no-debug-logging日志里重点看三行Started filter里给出的 filter 绝对路径是否真实存在、PID xx (/usr/lib/cups/filter/xxx) stopped with status里的退出码、以及Job stopped due to filter errors之前那几行。这三行基本能定位到是 PPD 指错了路径、filter 缺库崩了还是设备根本没响应。4. 扫描侧sane 后端加载、设备权限与 scanimage 参数化打印通了不代表扫描通了这两条链路唯一的共同点就是都要碰那个/dev/bus/usb/00X/00Y节点。扫描这边的问题更隐蔽因为scanimage -L给出的往往只是一句「No scanners were identified」不告诉你为什么。4.1 确认后端被 SANE 认到再确认设备被后端认到排查顺序必须从下往上先看.so有没有被拷到 SANE 的搜索路径下再看dll.conf里有没有把后端名列进去最后才看设备权限。# 1. 确认后端 .so 的落点注意发行版之间的路径差异 ls -l /usr/lib/x86_64-linux-gnu/sane/ 2/dev/null | grep -i mfp ls -l /usr/lib64/sane/ 2/dev/null | grep -i mfp ls -l /usr/lib/sane/ 2/dev/null | grep -i mfp # 2. 确认 dll.conf 里放行了这个后端名 grep -i -E mfp|vendor /etc/sane.d/dll.conf # 没有就手动加一行去掉注释符号 # sudo sh -c echo vendor_mfp /etc/sane.d/dll.conf # 3. 确认后端自己的配置文件里没有把设备禁用 ls /etc/sane.d/ | grep -i mfp cat /etc/sane.d/vendor_mfp.conf # 4. 从最底层确认 USB 层面能不能看到设备 sane-find-scanner | grep -i -E usb|vendor|model # 5. 最后才问 SANE 有没有可用扫描仪 scanimage -L这五步的顺序很关键。sane-find-scanner只做 USB 层枚举它能看到设备说明内核和 libusb 这条线是通的它看不到说明问题在更下层比如设备被别的内核模块独占、或者 USB 供电不足。scanimage -L看到设备但名字奇怪通常是后端配置里给了默认名不影响使用。如果.so放错了目录最省事的做法不是重新装一遍而是建一个软链接过去# 假设实际装在 /usr/lib/sane/但系统查找的是 multiarch 目录 sudo ln -s /usr/lib/sane/libsane-vendormfp.so.1 \ /usr/lib/x86_64-linux-gnu/sane/libsane-vendormfp.so.1 sudo ldconfig scanimage -L权限问题的表现是sane-find-scanner能看到设备scanimage -L也能列出来但真正开始扫描时报Permission denied或者Error during device I/O。原因是 USB 设备节点默认属主是root:root而普通用户不在lp组里。# 看设备节点的属主和权限 ls -l /dev/bus/usb/$(lsusb | grep -i vendor | awk {print $2} | tr -d :)/... # 把当前用户加进 lp 组重新登录生效 sudo usermod -aG lp $USER id $USER # 如果厂商装包时放了 udev 规则确认它被加载了 ls /etc/udev/rules.d/ | grep -i -E mfp|vendor sudo udevadm control --reload-rules sudo udevadm trigger提示加完组一定要重新登录或者新开一个 shellid里没出现lp就说明没生效很多人卡在这一步以为规则写错了。4.2 scanimage 的参数组合把「能用」调成「好用」设备认到之后scanimage的参数决定输出质量。这类后端支持的选项不统一最靠谱的做法是先让它自己报一遍能力清单再按清单取值# 列出该设备支持的全部选项和取值范围 scanimage -d vendor_mfp:libusb:001:004 --help # 一次完整调用A4 幅面、彩色、300dpi、TIFF 输出 scanimage \ -d vendor_mfp:libusb:001:004 \ --formattiff \ --modeColor \ --resolution300 \ --sourceFlatbed \ -l 0 -t 0 -x 210 -y 297 \ --brightness0 --contrast0 \ scan_$(date %Y%m%d_%H%M%S).tiff参数含义和常见取值参数作用常见取值与注意点-d/--device-name指定设备scanimage -L输出的完整串含libusb:bus:addr部分--format输出格式tiff/pnm/png/jpeg老后端对 png 支持不稳pnm 最保险--mode色彩模式Color/Gray/Lineart文档扫描用 Gray 体积小一半--resolution分辨率75/150/300/600/1200超过 600 老机器速度会明显拖慢--source进纸来源Flatbed平板 /ADF送稿器ADF 双面要额外参数-l -t -x -y扫描区域单位毫米A4 是 210×297留白多设一点避免截边--batch批量输出配 ADF 用--batchout_%03d.tiff末尾加--batch-countN实际用下来-x/-y设得比纸张略小一点比如 208×295比设满更稳因为部分后端在边界处会报Document feeder out of documents或者直接截断。批量扫描送稿器时--batch加--batch-prompt可以每页停一次等你换纸不带 prompt 就是一气呵成选哪个取决于你会不会卡纸。5. 排查清单五类翻车现场的现象、成因与处置下面这五条都是我在不同机器上真撞过的按发生频率从高到低排。每条都按「看到什么 → 为什么 → 怎么修」写方便对着日志直接翻。5.1 打印任务瞬间消失日志里是 Filter failed现象lp提交成功lpstat -o里任务存在不到一秒就没了error_log里是Job stopped due to filter errors往上翻能看到stopped with status 1或者Exec format error。原因两种。一是架构装反了——64 位系统装了 i386 目录下的 filter内核直接拒绝执行二是 filter 缺共享库启动瞬间就退出CUPS 只能给出一个笼统的失败状态。解决先file /usr/lib/cups/filter/filter名看它到底是 32 位还是 64 位 ELF跟uname -m对一下再ldd那个文件看not found。装反了就卸掉重装对应架构那一份缺库就按 2.2 的办法补齐。判断架构这一步能省掉大量瞎猜file /usr/lib/cups/filter/$(ls /usr/lib/cups/filter/ | grep -i mfp | head -n1) # 32 位会显示 ELF 32-bit64 位是 ELF 64-bit5.2 PPD 明明在建队列时却选不到现象ls /usr/share/cups/model/能看到 PPD 文件但lpinfo -m | grep 型号什么都没有图形界面里也搜不到。原因CUPS 的 model 目录有缓存服务不重启、也没触发过重新扫描时新拷进去的 PPD 不会立刻出现在列表里。另一种情况是 PPD 拷到了厂商私有目录比如/opt/.../ppd/那个目录根本不在 CUPS 的搜索路径里。解决重启 CUPS 再lpinfo -m一次如果还是没有直接用 PPD 的绝对路径建队列绕开搜索机制sudo systemctl restart cups lpinfo -m | grep -i 型号关键字 # 仍然没有就直接指绝对路径 sudo lpadmin -p MFP-01 -E -v usb://... -m /opt/vendor/ppd/xxx.ppd5.3 打印正常扫描报 Permission denied现象sane-find-scanner和scanimage -L都能看到设备一开始扫就报权限错误或者Error during device I/O。原因USB 设备节点属主是root:root、权限 664普通用户既不在lp组也没被 udev 规则覆盖。厂商装的 udev 规则有时用了旧的SYSFS{}语法在新版 udev 上不生效。解决先临时手动改属主验证判断——如果改完就能扫说明就是权限问题# 临时验证找到设备节点改属组 lsusb | grep -i vendor sudo chown root:lp /dev/bus/usb/001/004 sudo chmod 660 /dev/bus/usb/001/004 scanimage -L scanimage -d ... --formatpnm /tmp/t.pnm # 长期方案用户加进 lp 组 修 udev 规则用 ATTRS 语法 sudo usermod -aG lp $USERudev 规则里把SYSFS{idVendor}改成ATTRS{idVendor}把MODE0664和GROUPlp一起写上udevadm control --reload-rules udevadm trigger之后重新插拔设备。5.4 网络机型 ping 得通打出来是空白页或者卡住现象socket://192.168.x.x:9100建的队列任务显示完成纸上什么都没有或者任务一直卡在 processing最后超时。原因9100 是 RAW 端口如果设备其实只开了 IPP 或者 LPD往 9100 灌数据它会静默丢弃。另一种是设备休眠后 9100 端口响应慢CUPS 默认超时等不及。解决先用nc直接怼一下端口确认它到底收不收# 测 9100 通不通 nc -zv 192.168.x.x 9100 # 测 IPP 端口 nc -zv 192.168.x.x 631 # 如果 631 通、9100 不通改用 ipp URI sudo lpadmin -p MFP-01 -E -v ipp://192.168.x.x/ipp/print -m /path/to.ppd设备休眠导致的超时可以在队列上把等待时间调长-o job-sheetsnone -o printer-error-policyretry-job配合在设备侧关掉深度休眠。5.5 升过一次驱动之后同一台机器出现两个队列现象重装或者换版本之后打印机列表里同一台机器出现两条一条能用一条报错删掉能用的那条重启又回来。原因旧版安装脚本在/etc/cups/ppd/和printers.conf里留了残影新脚本又建了一条两条指向同一个 URI 但 PPD 版本不同。解决彻底清一次再重建别在图形界面里点删除# 停服务清队列配置再启服务 sudo systemctl stop cups sudo rm -f /etc/cups/printers.conf sudo rm -rf /etc/cups/ppd/* sudo systemctl start cups # 重新建一条确认只有一条 lpstat -pprinters.conf删掉等于清空所有本地队列机器多的话慎用改成手工lpadmin -x 队列名逐条删更稳。6. 固化成脚本把这次的排查顺序写成幂等的部署流程一台机器折腾完下一台还得再来一遍所以我习惯把上面这套顺序写成一个脚本重点不是「一键装完」而是「每一步都能重复执行、每一步都打印判断结果」。反复跑不会产生重复队列出问题能立刻知道断在第几步。#!/usr/bin/env bash # deploy_mfp.sh —— 幂等部署重复执行不会产生重复队列 set -uo pipefail VENDORmfp # 厂商前缀按实际 filter 文件名改 QUEUEMFP-01 PPD/usr/share/cups/model/vendor_mfp_series.ppd URIusb://Vendor/Model%20Series?serial0000000000 echo [1/6] 架构与依赖体检 uname -m FILTER$(ls /usr/lib/cups/filter/ | grep -i $VENDOR | head -n1 || true) if [ -z $FILTER ]; then echo filter 未安装先跑 install-printer.sh; exit 1 fi ldd /usr/lib/cups/filter/$FILTER 2/dev/null | grep not found \ echo 缺库先补齐再继续 exit 1 echo [2/6] 清理同名旧队列幂等关键 lpstat -p $QUEUE /dev/null 21 sudo lpadmin -x $QUEUE echo [3/6] 重启 CUPS 并刷新 model 缓存 sudo systemctl restart cups lpinfo -m | grep -qi $(basename $PPD .ppd) || echo PPD 未被索引将用绝对路径建档 echo [4/6] 建队列 sudo lpadmin -p $QUEUE -E -v $URI -m $PPD \ -o printer-is-sharedfalse -o PageSizeA4 sudo cupsenable $QUEUE sudo cupsaccept $QUEUE echo [5/6] 打印自检 lp -d $QUEUE -o mediaA4 /etc/hostname sleep 3 lpstat -o $QUEUE | grep -q . echo 任务仍在队列去看 error_log \ || echo 队列已清空检查出纸 echo [6/6] 扫描自检 scanimage -L | grep -qi $VENDOR \ echo 扫描设备可见 \ || echo 扫描不可见按 4.1 的五步顺序查set -uo pipefail里故意没加-e因为lpstat查不到队列本来就返回非零加了-e脚本会提前退出。第 2 步的lpadmin -x是幂等的核心不管之前有没有同名队列先删再建永远只有一条。配套的验证清单我一般贴在机器旁边装完逐条打勾检查项命令通过标准filter 架构匹配file /usr/lib/cups/filter/filter与uname -m一致PPD 可被索引lpinfo -m | grep 型号能搜到一行队列状态lpstat -p MFP-01显示 idle 或 processing实际出纸lp -d MFP-01 /etc/hostname队列清空且有纸扫描设备可见scanimage -L列出完整设备名实际扫描scanimage --formatpnm t.pnm文件非空且能打开血泪经验是第 5 步lpstat -o返回空不等于打印成功也可能是任务被静默丢弃了必须配合「有没有真的出纸」一起看。从那以后我每次部署完这类老驱动都会强制走一遍「提交任务 → 看 error_log 有没有 filter 报错 → 确认纸张真的出来」这三段不再相信界面上的绿色对勾。这套流程不复杂但能挡住九成的返工。希望帮到你。本文还有配套的精品资源点击获取