前言
由于某些软件并没有增加开启启动的服务,很多时候需要手工添加,一般我们都是推荐使用 systemd
写个系统服务,但是对于一些简单的脚本或者懒人来说,添加命令到 /etc/rc.local
文件更方便,但是自从 Debian 9 开始,Debian 默认不带 /etc/rc.local
文件,而 rc.local
服务却还是自带的:
我们可以看到系统自带了服务
root@debian:~# cat /lib/systemd/system/rc-local.service
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# This unit gets pulled automatically into multi-user.target by
# systemd-rc-local-generator if /etc/rc.local is executable.
[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target
[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no
并且它是默认关闭的
root@debian:~# systemctl status rc-local.service
● rc-local.service - /etc/rc.local Compatibility
Loaded: loaded (/lib/systemd/system/rc-local.service; enabled-runtime; vendor preset: enabled)
Drop-In: /usr/lib/systemd/system/rc-local.service.d
└─debian.conf
Active: failed (Result: exit-code) since Mon 2023-06-19 13:01:32 CST; 1min 32s ago
Docs: man:systemd-rc-local-generator(8)
Process: 517124 ExecStart=/etc/rc.local start (code=exited, status=1/FAILURE)
CPU: 7ms
启用服务
那么如果我们想启用的话,首先要添加一个/etc/rc.local
文件:
cat <<EOF >/etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
exit 0
EOF
在exit 0之前写要启动的命令即可
然后赋予它执行权限
chmod +x /etc/rc.local
接着启动服务
systemctl enable --now rc-local
root@debian:~# systemctl enable --now rc-local
The unit files have no installation config (WantedBy=, RequiredBy=, Also=,
Alias= settings in the [Install] section, and DefaultInstance= for template
units). This means they are not meant to be enabled using systemctl.
Possible reasons for having this kind of units are:
• A unit may be statically enabled by being symlinked from another unit's
.wants/ or .requires/ directory.
• A unit's purpose may be to act as a helper for some other unit which has
a requirement dependency on it.
• A unit may be started when needed via activation (socket, path, timer,
D-Bus, udev, scripted systemctl call, ...).
• In case of template units, the unit is meant to be enabled with some
instance name specified.
Job for rc-local.service failed because the control process exited with error code.
See "systemctl status rc-local.service" and "journalctl -xe" for details.
解决报错
其实上面的警告可以无视,但是下面的报错我们要找一下原因
我们按提示运行以下看看报错
systemctl status rc-local.service
● rc-local.service - /etc/rc.local Compatibility
Loaded: loaded (/lib/systemd/system/rc-local.service; enabled-runtime; vendor preset: enabled)
Drop-In: /usr/lib/systemd/system/rc-local.service.d
└─debian.conf
Active: failed (Result: exit-code) since Mon 2023-06-19 13:22:16 CST; 1min 40s ago
Docs: man:systemd-rc-local-generator(8)
Process: 590479 ExecStart=/etc/rc.local start (code=exited, status=1/FAILURE)
CPU: 7ms
Jun 19 13:22:16 debian systemd[1]: Starting /etc/rc.local Compatibility...
Jun 19 13:22:16 debian rc.local[590482]: Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
Jun 19 13:22:16 debian rc.local[590482]: At least one of these environment variable is needed to run this program
Jun 19 13:22:16 debian systemd[1]: rc-local.service: Control process exited, code=exited, status=1/FAILURE
Jun 19 13:22:16 debian systemd[1]: rc-local.service: Failed with result 'exit-code'.
Jun 19 13:22:16 debian systemd[1]: Failed to start /etc/rc.local Compatibility.
可以看到提醒我们java的环境变量没有配置,但是我们其实有配置过环境变量
root@debian:~# echo $JAVA_HOME
/home/java/jdk1.8.0_301
所以到底是为什么呢?
其实我们是在 /etc/profile
文件中设置了环境变量,但是 systemd
这个系统服务管理器可能并不能看到这些变量。因为 systemd
并不会加载 /etc/profile
,所以在 /etc/profile
中设定的环境变量在 systemd
启动的服务中可能无法获取到。
解决的办法就是在 systemd
的服务定义文件中设定环境变量。你可以尝试在 rc.local
服务的 systemd
单元文件中设置 JAVA_HOME
。
nano /lib/systemd/system/rc-local.service.d/debian.conf
在 [Service]
段下添加 Environment
行:
[Service] Environment=JAVA_HOME=/home/java/jdk1.8.0_301
我们保存并退出,然后重新加载‘systemd‘的配置文件
systemctl daemon-reload
之后再尝试启动‘rc.local‘服务就发现成功啦~
systemctl start rc-local.service
接着我们重新开启下systemd里rc-local服务的开机自启动就可以了
systemctl enable --now rc-local