简介: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调libsane,libsane读/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 -u+x \) -print0 \ | xargs -0 file | grep -E "ELF" # 3. 对 64 位那一份逐个检查动态链接 find ./cdroot/Linux/x86_64 -type f -perm -u+x -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 -u+x表示「属主有执行位」,用它筛出来的基本就是会被 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://厂商/型号?serial=xxx,这个串可以用lpinfo -v让 CUPS 自己枚举出来:
# 列出 CUPS 当前能看到的全部后端设备 lpinfo -v | grep -i usb # 输出形如: # direct usb://Vendor/Model%20Series?serial=0000000000 # 用枚举出来的 URI 建队列,-m 直接指向 PPD 绝对路径最稳 sudo lpadmin -p MFP-01 \ -E \ -v "usb://Vendor/Model%20Series?serial=0000000000" \ -m /usr/share/cups/model/vendor_mfp_series.ppd \ -o printer-is-shared=false \ -o PageSize=A4 # 启用并接受任务(新队列默认可能是 stopped 状态) sudo cupsenable MFP-01 sudo cupsaccept MFP-01 # 打一张最小测试页,别用图形界面,排除前端干扰 lp -d MFP-01 -o media=A4 /etc/hostname lpstat -o MFP-01参数逐个说明:-E表示建完立即启用并接受任务,等价于后面两条cupsenable加cupsaccept;-v是设备 URI,USB 直连用usb://,网络机型用socket://IP:9100或ipp://IP/ipp/print;-m既可以给 PPD 的绝对路径,也可以给lpinfo -m里输出的那串模型名,给绝对路径更不容易错;-o printer-is-shared=false在只想本机用的时候关掉共享,能省掉一堆 mDNS 注册带来的干扰;-o PageSize=A4会写进队列默认选项,比在每个应用里单独设靠谱。
如果任务提交后一直停在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提示:加完组一定要重新登录或者新开一个 shell,
id里没出现lp就说明没生效,很多人卡在这一步以为规则写错了。
4.2 scanimage 的参数组合:把「能用」调成「好用」
设备认到之后,scanimage的参数决定输出质量。这类后端支持的选项不统一,最靠谱的做法是先让它自己报一遍能力清单,再按清单取值:
# 列出该设备支持的全部选项和取值范围 scanimage -d "vendor_mfp:libusb:001:004" --help # 一次完整调用:A4 幅面、彩色、300dpi、TIFF 输出 scanimage \ -d "vendor_mfp:libusb:001:004" \ --format=tiff \ --mode=Color \ --resolution=300 \ --source="Flatbed" \ -l 0 -t 0 -x 210 -y 297 \ --brightness=0 --contrast=0 \ > 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 用,--batch=out_%03d.tiff,末尾加--batch-count=N |
实际用下来,-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-bit",64 位是 "ELF 64-bit"5.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 "..." --format=pnm > /tmp/t.pnm # 长期方案:用户加进 lp 组 + 修 udev 规则用 ATTRS 语法 sudo usermod -aG lp "$USER"udev 规则里把SYSFS{idVendor}改成ATTRS{idVendor},把MODE="0664"和GROUP="lp"一起写上,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-sheets=none -o printer-error-policy=retry-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 VENDOR=mfp # 厂商前缀,按实际 filter 文件名改 QUEUE=MFP-01 PPD=/usr/share/cups/model/vendor_mfp_series.ppd URI="usb://Vendor/Model%20Series?serial=0000000000" 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 2>&1 && 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-shared=false -o PageSize=A4 sudo cupsenable "$QUEUE" && sudo cupsaccept "$QUEUE" echo "[5/6] 打印自检" lp -d "$QUEUE" -o media=A4 /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 --format=pnm > t.pnm | 文件非空且能打开 |
血泪经验是第 5 步:lpstat -o返回空不等于打印成功,也可能是任务被静默丢弃了,必须配合「有没有真的出纸」一起看。从那以后我每次部署完这类老驱动,都会强制走一遍「提交任务 → 看 error_log 有没有 filter 报错 → 确认纸张真的出来」这三段,不再相信界面上的绿色对勾。这套流程不复杂,但能挡住九成的返工。希望帮到你。
本文还有配套的精品资源,点击获取