背景
CentOS 运维过程中 在 /etc/rc.d/rc.local 写入开机需要运行的命令,是在CentOS5-CentOS6 中常见做法。但是在CentOS7中,却出现了 rc.local 中命令,系统启动后却不执行的情况。
原因分析
rc.local 是 Sysvinit技术用于CentOS5-6的"init"进程在启动过程中最后执行的任务。但是众所周知,CentOS7和CentOS8 是使用了Systemd技术启动,开机不会运行init进程。
为了兼容,CentOS 7 官方提供的方法是默认提供了一个名为“rc-local” 的 systemd 服务,负责系统启动后执行 rc.local 中的命令。但是有一个前提: /etc/rc.d/rc.local 必须是可执行(默认是不可执行的)。
解决方案
“激活” systemd 的"rc-local" 服务
(1) 在 /etc/rc.d/rc.local 写入你需要执行的linux命令
# vim /etc/rc.d/rc.local
#!/bin/bash
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.
touch /var/lock/subsys/local
# 写入你要执行的命令
(2) 给 /etc/rc.d/rc.local 添加 可执行权限
# chmod a+x /etc/rc.d/rc.local
(3) 将 rc-local 服务设置成开机启动(默认状态是 static,会被其他service服务调用执行。不过还是修改一下,以防那个服务被停用就牵连了)
# systemctl enable rc-local
附注
/usr/lib/systemd/system/rc-local.service 文件内容解释
[Unit]
# 服务描述
Description=/etc/rc.d/rc.local Compatibility
# 只有 rc.local 这个文件有可执行权限才执行service(这是 rc.local 开机不启动的原因!)
ConditionFileIsExecutable=/etc/rc.d/rc.local
# 如果 network 需要启动,则等待network启动之后再启动本服务
After=network.target
[Service]
# Type字段定义启动类型。
# forking的意义: ExecStart字段将以fork()方式启动,此时父进程将会退出,子进程将成为主进程
Type=forking
# 启动命令
ExecStart=/etc/rc.d/rc.local start
TimeoutSec=0Remain
# RemainAfterExit字段设为yes,表示进程退出以后,服务仍然保持执行。
# 这样的话,一旦使用systemctl stop命令停止服务,ExecStop指定的命令就会执行,从而重新开启触摸板。
RemainAfterExit=yes