最近在做一个Python爬虫程序,会自动爬取一个社区上的图片保存到本地,然后挑一些喜欢的保存下来,嘿嘿。我打算用香橙派来跑这个爬虫,同时把下载的图片保存到一个外接的U盘里,因为sd卡的空间不是很大。
Linux既然要挂磁盘,那必然得是我们的老朋友/etc/fstab
,但是fstab好像不太聪明的样子,它只在开机时挂载一次,如果开机后U盘掉线再插回来时,它的挂载状态就丢失了,又要手动挂载一次。
虽然写个Python脚本定时检测并主动调用命令行挂回来不是什么难事,但这个做法我怎么都觉得不够优雅,肯定有更好的解决办法。
经过一段时间的搜寻,我找到了一个叫autofs的软件,它不仅可以自动把掉线的u盘挂载回来,还可以在长时间不用的时候自动卸载U盘,感觉这个特性对机械硬盘来说非常有用,卸载掉之后机械硬盘可以停转休眠,能减少电量消耗和节省硬盘寿命。
autofs是个通用软件,除了挂载本地block设备,还可以挂载NFS,samba等协议设备。“通用”的东西一般都比“专用”的东西用起来要麻烦。经过一段时间的查阅文档,我大概了解autofs应该怎么用了。
首先autofs是有配置文件的,和fstab是差不多的作用,用来定义一些挂载规则。
autofs的配置文件分三种:
- autofs自身的配置文件
/etc/autofs.conf
:用来修改autofs核心的一些功能的,一般不用修改这个文件 - 主映射文件
/etc/auto.master
:用来存储所有子映射文件的一个文件。这个文件只能存在一个,一般不用修改这个文件 - 子映射文件
/etc/auto.xxx
:用来存储所有具体映射规则的文件,可以存在多个(xxx为自定义名字)
autofs的挂载规则并不是一股脑全部写在主映射文件里的,而是分散写到各个子映射文件里,然后再在主映射文件里写上子映射文件的路径,这样就能定义好映射规则了。这个机制类似于nginx配置文件的include指令,但又稍微有些不同。
配置文件具体的关系用yaml格式描述如下:
- autofs.conf(自身配置文件)
- auto.master(主映射文件)
- auto.foo(子映射文件foo)
- 挂载规则1
_ 挂载规则2
- auto.bar(子映射文件bar)
- 挂载规则1
- 挂载规则2
autofs.conf
和auto.master
是并列的关系,而auto.xxx
则隶属于auto.master
下。而具体的一个个挂载规则是写到子映射文件里,虽然层次有点多,但也还算比较好理解。
我们要挂载u盘的话,首先得创建一个自己的子映射文件,这个文件可以自己取一个名字,我们就叫custom-usb
好了。取好了名字,就可以创建这个子映射文件了/etc/auto.custom-usb
。根据autofs的约定,这个文件一般放在etc目录下,以auto.
前缀开始,自定义结尾。当然约定只是约定,放到别的位置也是没有问题的。
接着我们需要编辑主配置文件引用一下刚创建的/etc/auto.custom-usb
。这里又有一个小约定:要往主映射文件下面添加内容时,我们一般不直接修改auto.master
,而是在/etc/auto.master.d
目录下新建一个以.autofs
结尾的文件,然后auto.master
它会自动扫描这个目录里面的.autofs文件并include到它自己的内容里面。这一点和nginx的include指令是一样的。这里我们创建/etc/auto.master.d/custom-usb.autofs
,之所以也叫custom-usb.autofs
只是为了方便联系到我们的/etc/auto.custom-usb
文件而已,并没有强制一定要和子映射文件的文件名一样。
创建好了/etc/auto.master.d/custom-usb.autofs
文件之后,就可以打开编辑了。这个文件的语法和主配置文件是一样的,文件内容为/- /etc/auto.custom-usb
,好了以后保存关闭。(前面的/-
是以“直接映射”的方式读取这个子映射文件,至于直接映射和间接映射后面会讲解)
接着回来编辑先前创建的子映射文件/etc/auto.custom-usb
,我们填写/mnt/my-usb-1 -fstype=auto,async,noatime,nofail,rw :/dev/disk/by-partuuid/48375893-01
然后保存关闭。
这个文件的内容根据空格可以分成三部分:
第一部分/mnt/my-usb-1
是挂载点,这很好理解。
第二部分是以-
开头的一大堆参数,这些参数以逗号作为分隔,会被传递给mount命令。
第三部分是以:
开头的设备路径,也就是要被挂载的分区的设备。这里推荐使用uuid的形式进行访问,当然你喜欢用/dev/sda[0123456]
这种编号访问也是没问题的,只是重启后可能会乱。
一切完毕之后我们保存关闭子映射文件/etc/auto.custom-usb
,执行sudo systemctl reload autofs
来重新加载我们刚刚写的配置文件。
接着我们打开/mnt
目录,会发现没有/mnt/my-usb-1
这个目录啊?其实是这样的,只有当你访问这个目录的时候,U盘才会被挂载,所以ls命令看不到是很正常的。我们可以直接cd进/mnt/my-usb-1
这个目录,或者在sftp窗口里直接输入这个路径,就会发现:诶!这个目录突然出现了。过一段时间没有访问之后,这个设备又会被重新卸载掉。
最后提一下前面提到的直接映射和间接映射是什么,这两个都是autofs的映射模式。首先说一下间接映射吧。间接映射一般用在要挂载的设备很多的情况下,比如插入了100块硬盘,都要挂载到/mnt/harddisks/xxx
这个目录下,你就可以把主映射文件里的/-
换成/mnt/harddisks
,然后在子映射文件里,每一行的第一部分,就不用写绝对路径了,可以就写一个yingpan1
,yingpan2
,然后挂载的时候autofs会自动挂载到/mnt/harddisks/yingpan1
和/mnt/harddisks/yingpan2
这样的路径上。除了手写yingpan1
,yingpan2
,autofs还支持自动按编号挂载设备。如果想移动挂载点,只需要在主映射文件里修改/mnt/harddisks
这个路径就好了,就不用在子映射文件一个个改了,会省事一点。
反过来,直接挂载就是不搞这么的复杂,直接在子映射文件里写绝对路径就好了,就像上面的例子一样,然后主映射文件里的路径就必须要写成/-
(一个字不能差)这个死路径。一般设备少的话用直接挂载会省事一丢丢(真的就是一丢丢)。当然你喜欢的话用间接挂载也是完全没有问题的。
最后,如果你能读英文,可以看看autofs的手册:
- 主映射文件的文件格式:
man 5 auto.master
- 子映射文件的文件格式:
man 5 autofs