过去几年时间里,大部分Linux发行版都更改了启动的方式,基本上那些老的关于如何配置rc.local的资料都作废了,虽然用还是可以用的,但是不推荐。有一点没有改变,Linux还是沿用原来的设计:第一个启动的进程会成为之后所有进程的父进程,原来这个进程是/sbin/init,现在是/lib/systemd/systemd,它们的PID都是1。
启动进程会完成大多数工作,然后显示用户界面。你可以通过dmesg命令查看系统的欢迎信息,这些信息被保存在/var/log/kern.log文件里。
启动进程是用户空间的起始点。在用户空间里,你的程序也可以修改系统的行为,而不需要更改内核的源码。一般来说,Linux发行版实现了UNIX的SystemV启动模式,通过SystemV你可以定义进程的运行等级,包括单用户模式、终端模式、图形界面模式以及关机。
现在Jessie系统已经不使用service命令了,你应该使用systemctl将服务添加到systemd,后会在这个文件夹下出现,你不应该手动去修改这些链接,如图2-11所示。
图2-11
dmesg会显示系统的启动信息,如图2-12所示。
图2-12
在/etc文件夹下的rc0到rc6文件里定义的启动项总会在系统启动时启动,这与定义的启动等级是无关的。
/etc/init.d下的脚本可以用来启动你的数据库、服务器以及其他一些服务。这些服务可以通过status命令来查看状态、通过reload命令来重启。reload命令会重新检查配置文件,但不会完全重启服务。
$ sudo /etc/init.d/couchbase-server status
我们上面讨论的主要是Sys-V启动方式。这种方式有一个很大的缺点,就是效率低下,接下来介绍一种更高效的启动方式。
Systemd的特点是会并发地启动进程。在设定好一个启动对象后,Systemd会尝试解决这个启动对象的依赖关系,而不会启动无关的进程。Systemd的配置文件在/etc/systemd/system下。需要注意的是,Systemd使用的是systemctl命令,比如:
$ sudo systemctl restart ssh
会重启ssh服务。出于兼容性的考虑,Systemd没有废弃service命令,比如:
$ sudo service apache2 reload
还是可以正常工作的。
在/etc/systemd/system/multi-user.target.wants文件夹下你会发现很多像cron.service这样的文件。通过ls命令检查,你会发现这些链接指向/lib/systemd/system文件夹下的同名文件,简单来说,它们处理了文件之间的依赖关系。接下来我们会介绍crontab:
$ sudo systemctl enable postgresql.service
这条指令创建了一个链接,然后postgreSQL会在系统启动时运行。
$ sudo systemctl daemon-reload
这条指令会使这些改变对systemd立即生效。
虽然运行等级在systemd模式下已经没有什么作用了,但是你还可以通过who-r指令来查看运行等级。
出于兼容性考虑,Systemd系统保留了init.d等脚本文件。
Systemd是一个复杂的系统,包括systemd.unit到systemd.slice等组件,这些组件都有自己的帮助页面,如图2-13所示。
图2-13
Systemd能够自动处理文件之间的链接关系,但有时你可能需要手动管理链接关系,这时就需要ln命令了。
ln命令能够创建一个文件的链接,然后就可以让一个文件出现在系统的两个不同位置了:
$ sudo ln -s /usr/share/doc/python-numpy/THANKS.txt $ numpy-THANKS.txt
建立链接后,输入“ls –l”,你会发现这是一种特别的文件(一个指向实际存储的文件的链接)。编辑numpy-THANKS.txt文件,然后你会发现原本的THANKS.txt也被更改了。
另外,这里的-s代表软链接。软链接的特点是被链接的文件甚至可以不存在,特别适配可插拔的设备。
这种链接被称为符号链接,这是因为它链接到的是文件的文件名,而不是文件实际的数据。
$ sudo ln /etc/bluetooth/main.conf mybluetooth.conf
以上命令生成了一个硬链接,相当于一个文件现在在不同的两个位置有了两个不同的名字,但这并不意味着这两个是同一个文件。创建一个硬链接会类似于复制生成了一个新的文件,对原文件的修改不会对硬链接文件产生影响。
启动脚本一般是为守护进程这样需要一直保持运行状态的进程所设计的,对于其他一些周期性运行的进程(比如家务管理),要使用cron系统来进行更好的管理。cron会在/etc目录下寻找自己的配置文件,然后根据这些配置文件来工作。那么应该如何寻找对应的配置文件呢?这时就要用到locate命令了。locate命令在系统上默认是不会安装的,所以要先安装locate命令:
$ sudo apt-get install mlocate
然后输入命令:
$ sudo updatedb
接下来通过locate命令寻找配置文件:
$ locate cron-
locate命令是通过自己存储的文件数据库来工作的,这个数据库每天会通过cron来完成周期性的更新。如果你想要手动更新这个数据库,只需要输入命令“sudo updated”即可。
find命令与locate命令具有类似的功能。find命令允许你通过文件的文件名、大小以及修改时间来在某个文件夹或者是整个文件系统下寻找文件。find命令有很复杂的功能,比如具有locate并不支持的正则表达式。同时由于它是直接通过文件系统寻找文件的(相比之下locate通过一个缓存的数据库来寻找文件),所以它一般耗时会更久一些。如果你想要使用find命令来完成以上用locate命令完成的任务,就可以输入:
$ find / -name '*cron*'
在搜索结果中会出现anacron相关的文件。如果你不希望搜索到这些文件,那么可以使用正则表达式‘cron*’。find命令一般会有大量的输出,所以最好把输出信息通过管道重定向到其他命令里去。
在系统上使用cron可以通过crontab命令。输入“crontab –e”命令后就可以编辑对应的cron配置文件了。下面来看一个示例。
45 05 * * 1-5 calendar | mail -s 'Your calendar' me@myemailaddress.com
这条命令的意思是在每天上午发送对应的日历信息到你的邮箱。前5个参数与命令执行的周期相关,可以用@daily或者@hourly来代替。如果想了解更多有关crontab的信息,你可以输入“man 5 crontab”来查看帮助文档。
在运行上面的命令时,系统可能会提示你mail并没有被安装,那么你需要先安装一个邮件软件,比如说ssmtp。
提示
正则表达式:find命令支持在查找时使用正则表达式。正则表达式是一个非常大的主题,这里就不详细介绍了。作为一项广泛应用的技术,它非常值得学习。一些用户不希望使用Systemd的启动方式,可以使用操作系统提供的其他选择。对于Ubuntu,你可以使用Upstart。对于Raspbian,你可以使用Devuan发行版,它使用的是经典的Sys-V启动。
crontab中的@reboot配置符可以让我们在启动时打开一个服务。相较于之前提到的systemd配置,crontab的配置更为简单一些。在使用crontab配置启动服务时有两点需要特别注意一下:
· 在启动时$PATH环境变量是无效的,因为$PATH环境变量只有在导入了.bashrc文件后才能生效。在启动时,还没有对应的终端环境,所有使用了$PATH环境变量的命令要手动写出完整的路径,比如/home/pi/bin/test.sh,同时也要确认文件权限是否正确。
· systemd是并行进行服务启动的。这样一来,可能在你的@reboot对应的命令执行时网络连接的服务还没有启动完成。如果你觉得自己可能遇到了类似的问题,那么你应该在crontab的配置信息里将时间延后几秒钟。
@reboot sleep 10; /usr/bin/python3 /home/pi/Documents/ Python_Projects/hello_gpio.py
安装mlocate后系统会添加一些脚本到/etc/cron.daily,之后locate命令会每天自动更新它的数据库,如图2-14所示。
图2-14
在crontab的配置文件里你会看到anacron(被用来管理那些已经很久没有启动的进程)。在anacrontab配置里,你可以手动定义一个最长时间,超过这个时间以后anacron就执行指定的进程。anacron常常被用来管理备份脚本,这是下一节将要讨论的内容。