本人非计算机专业,折腾起linux实在是太难了,经过几天的研究,总算把上一版方案 https://20122012.xyz/index.php/archives/130/ 不足之处给解决了,现记录如下:

一.锐角云等X86机器

执行代码拉取镜像并运行容器,这里仍然选择tigerj/cups-airprint的,因为其他的我都试过识别不了我的M1005,不知道是不是个案。而且这个镜像带avahi,能实现airprint,支持安卓及苹果设备直接使用系统自带打印服务搜索到打印机,非常方便。只是有点瑕疵,让我花了点时间解决了。

docker run \
       --name=cups \
       --restart=always \
       --net=host \
       -v /var/run/dbus:/var/run/dbus \
       -v ~/airprint_data/config:/config \
       -v ~/airprint_data/services:/services \
       --device /dev/bus \
       --device /dev/usb \
       -e CUPSADMIN="admin" \
       -e CUPSPASSWORD="password" \
       tigerj/cups-airprint

后面步骤都一样,参考老版步骤,选择驱动,共享打印机,直到cups里能打印出测试页面。这时如果去电脑或者手机的打印服务里搜索打印机是搜索不到的。接下来执行命令

docker exec cups service dbus start
docker exec cups service avahi-daemon start

执行之后去电脑或者手机系统自带的打印服务里搜索打印机,怎么样,是不是搜索到了?

这时候打印机能正常工作了,但是不能关,一关,再打开,打印作业就会被挂起,无法继续打印,只有手动重启cups,要想实现打印机上电自动重启cups,解决方法如下:

/etc/udev/rules.d目录下新建一条规则,如m1005.rules
内容如下:

ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_VENDOR_ID}=="03f0", ENV{ID_MODEL_ID}=="3b17", RUN+="/root/cupsstart.sh"

ACTION=="remove", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{PRODUCT}=="3f0/3b17/100", RUN+="/root/cupsstop.sh"

这步操作是让系统在发现打印机接入及断开时执行脚本,这段代码也是百度来的,原本addremove两段代码是一样的,唯一区别是最后执行的脚本不一样,但是实际执行的时候我发现只有打印机接入能执行add这段代码,而打印机断电,不能执行remove这段代码,继续百度,从https://blog.csdn.net/weixin_30610431/article/details/114562335找到了答案,执行 udevadm monitor --kernel --property --subsystem-match=usb之后分别给打印机通电和断电,对比输出发现,断电时没有 MODEL_ID参数,所以代码不执行了,根据实际输出,将断电代码如上修改之后,就顺利执行了。其中add段代码中的03f0 3b17 两个数据要跟你你的实际修改,这两个参数可以通过执行lsusb查看到
然后在/root目录里建立两个脚本:cupsstart.shcupsstop.sh

#!/bin/sh
docker restart cups
docker exec cups cupsaccept M1005
docker exec cups service dbus start
docker exec cups service avahi-daemon start

这个脚本实现系统一发现打印机接入,就重启cups容器,并设置打印机接受打印任务,另外将avahi服务启动起来。

#!/bin/sh
docker exec cups cupsreject M1005

这个脚本是实现当打印机断电了,设置打印机拒绝打印任务,为什么要这么设置呢,因为打印机断电之后重新上电,cups会接受打印任务,但是却不打印,这时如果重启,重复发送的打印任务全部会打印出来,为了避免这种情况发生,需要在打印机断电之后设置cups拒绝打印任务。
好了这样就完美实现,打印机上电自动启动cups,断电cups拒绝打印任务,并且完美支持airprint,安卓,ios,电脑都能直接搜索到打印机。

二.我家云、贝壳云、N1等arm机器

docker run \
       --name=cups \
       --restart=always \
       --net=host \
       -v /var/run/dbus:/var/run/dbus \
       -v ~/airprint_data/config:/config \
       -v ~/airprint_data/services:/services \
       --device /dev/bus \
       --device /dev/usb \
       -e CUPSADMIN="admin" \
       -e CUPSPASSWORD="password" \
       jysky007/cups:v1

花了点时间修改了镜像,直接支持airprint了。
我既有我家云也有N1,都刷的是荒野无灯大神的小钢炮系统,这个系统非常精简,里面管理热插拔硬件的是mdev 这个是简化版的udev,研究了许久只实现了打印机上电自动重启cups,也可以啦。方法如下:

/etc/mdev.conf文件的最下面添加一行:

usb/lp0       0:0 660   @/root/cupsstart.sh

然后执行/etc/init.d/S10mdev restart重启mdev服务。

这表示识别打印机接入,就执行/root/cupsstart.sh脚本,脚本内容:

#!/bin/sh
docker restart cups

记得把脚本权限改成0777

本来还写了打印机断电关闭docker的脚本,但是不成功,不知可有高手能解决。