Linux启动顺序中决定程序启动项的在init这里,分为两大步骤:按级别加载/etc/rc(0-6).d目录下的启动脚本;加载/etc/rc.local文件。所以设置启动项的方案按原理就分为这两种方式。
较简单的方式就是直接vim修改/etc/rc.local文件,将其作为一个shell脚本来编辑,将自己的启动命令编辑到脚本中,例如:
#!/bin/sh
/usr/bin/supervisord -c /data/www/liveplay/confs/bjyg/liveplay.conf
本文重点介绍的是第一种,比较复杂
首先,所谓的按级别分,其实就是按场景来分,像rc.local的方式是直接一刀切,无论如何都会被加载执行的,而有时我们想按照不同的场景来选择是否加载,甚至是加载不同的启动脚本,这时就要用rc(0-6)按场景来分了。
我们先看下Linux的7种场景:
运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登陆
运行级别2:多用户状态(没有NFS)
运行级别3:完全的多用户状态(有NFS),登陆后进入控制台命令行模式
运行级别4:系统未使用,保留
运行级别5:X11控制台,登陆后进入图形GUI模式
运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动
我们可以看下rc5和rc6的区别:
可以看到rc5是图形化启动场景,里面的文件都是S开头,代表Start,服务启动脚本;rc6是系统关闭,里面的文件都是K开头,代表kill,服务关闭脚本。文件名中间的数字代表的是优先级,决定执行的顺序。文件名剩下的英文部分代表服务名称。
我这里虽然把这些文件叫“脚本”,其实本质上是link,可以随便进入一种rc.d里确认下:
所有link都复用一套脚本,存放在/etc/init.d文件夹下,方便维护。
再来看下脚本的内容,核心代码如下;
根据命令中变量的值决定执行不同的逻辑
我们知道了原理,但是毕竟直接自己创建link、自己设置脚本权限等很容易出现人为的错误,所以linux把rc0-rc6设置开启项的这种方式封装成了内部命令。
早期的Linux版本是用chkconfig命令来设置rc的link,设置开机启动项;用service命令调用服务的start、stop、restart、status等函数。在现在主流Linux版本已经将这两个命令合并成一个systemctl命令了,映射关系如下:
任务 | 旧指令 | 新指令 |
使某服务自动启动 | chkconfig –level 3 httpd on | systemctl enable httpd.service |
使某服务不自动启动 | chkconfig –level 3 httpd off | systemctl disable httpd.service |
检查服务状态 | service httpd status | systemctl status httpd.service |
显示所有已启动的服务 | chkconfig –list | systemctl list-units –type=service |
启动某服务 | service httpd start | systemctl start httpd.service |
停止某服务 | service httpd stop | systemctl stop httpd.service |
重启某服务 | service httpd restart | systemctl restart httpd.service |
像mysql、docker、dnsmasq、ssh等成品服务,都自带开机项脚本,直接通过以上systemctl的方式设置即可。如果是我们自己写的shell脚本,又不想放在rc.local中,也要按照rc0-rc6的方式来设置,怎么办?
将DIV的脚本复制到/etc/init.d目录下,并chmod 755设置下权限。
执行命令,将脚本设置到rc0-rc6中:
#update-rc.d my-test start 20 2 3 4 5 . stop 20 0 1 6
如果设置成功,会有如下的warning信息:
执行完update-rc.d命令后需要自己去rc0-6里去检查下是否成功创建link,因为如果脚本缺少stop、start等函数会使update-rc.d命令失败,但控制台不会有提示。
上面命令等同于:
#update-rc.d my-test defaults 20
最后一个参数代表在该运行级别下第几个执行
如果剔除设置,执行命令:
#update-rc.d -f my-test remove