Jarvis' Blog 总有美丽的风景让人流连

Linux 配置开机启动程序

2022-07-18
Jarvis
Wiki_Ubuntu

以 Ubuntu 20.04 为例, Linux 系统配置系统级别的开机启动通常会用到 systemd 程序集.

Systemd 就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。

根据 Linux 惯例,字母d是守护进程(daemon)的缩写。 Systemd 这个名字的含义,就是它要守护整个系统。

本文会长期更新, 列举一些经典的开机启动配置清单.

1. 基础

本文讨论的开机启动程序配置都是基于 systemd 的, 这应该适用于大多数 Linux 发行版.

提示

Windows Subsystem for Linux 2 (WSL2) 除外. 由于 WSL2 是运行在 Windows 之上的, 而 systemd 系列程序是开机就要启动的, 所以 WSL2 上无法使用 systemd, 而是仍然使用 init 的方式. 比如 service xxxx start. 其服务程序一般保存在 /etc/init.d/ 目录下.

systemd 的介绍可以参考阮一峰的网络日志: Systemd 入门教程:命令篇.

systemd 是个程序集, 包含了一系列的命令, 其中的 systemctl 就是我们今天主要用于配置开机启动程序的命令. 另外一个 journalctl 是用于查看日志的命令.

命令记忆方法:

  • systemctl: system control
  • journalctl: journal control

  • 启动停止服务相关操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 启用服务(注意不是启动), 实际上是创建了个软连接. 启用服务后系统启动后会启动该服务
sudo systemctl enable xxxxx.service

# 禁用服务. 禁用服务后系统启动后不会启动该服务. 禁用服务不会删除服务, 仅仅是从启动列表中去掉该服务.
sudo systemctl disable xxxxx.service

# 启动服务. 手动启动服务, 不需要等到重启电脑就能启动.
sudo systemctl start xxxxx.service

# 查看服务状态
sudo systemctl status xxxxx.service

# 停止服务
sudo systemctl stop xxxxx.service
  • 查看更多日志
1
2
# -u 的意思是 unit. 因为 systemd 的服务都是看作一个一个 unit 的.
sudo journalctl -u xxxx.service

2. 配置清单

systemd 系统级别的服务配置都放在 /lib/systemd/system/ 目录下.

2.1 NVIDIA GPU 风扇控制

GPU 风扇控制使用 coolgpus. 使用 pip 安装, 命令如下:

1
pip install coolgpus

启动命令为

1
coolgpus --temp 15 85 --speed 20 90

那么为了开机自动执行上面的命令, 我们新建文件 /lib/systemd/system/gpu_fan.service, 写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=GPU fan Adjust
Documentation=

[Service]
Type=simple   # use simple because coolgpus runs without forking
ExecStart=/home/jarvis/miniconda3/bin/coolgpus --temp 15 85 --speed 20 90
TimeoutSec=0
GuessMainPID=no

[Install]
WantedBy=multi-user.target

其中 ExecStart 后面的内容就是我们要执行的命令, 注意 coolgpus 要根据命令的实际路径修改为完整路径.

保存后启用, 启动, 查看状态:

1
2
3
sudo systemctl enable gpu_fan.service
sudo systemctl start gpu_fan.service
sudo systemctl status gpu_fan.service

看到 active(running) 即说明服务正常在跑了.

2.2 shadowsocks-libev 服务

安装 shadowsocks-libev 工具.

1
sudo apt install shadowsocks-libev

安装完成后会发现安装程序已经创建好相关服务了, 路径为 /lib/systemd/system/shadowsocks-libev.service

该文件中默认是服务端的配置.

服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#  This file is part of shadowsocks-libev.
#
#  Shadowsocks-libev is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  This file is default for Debian packaging. See also
#  /etc/default/shadowsocks-libev for environment variables.

[Unit]
Description=Shadowsocks-libev Default Server Service
Documentation=man:shadowsocks-libev(8)
After=network-online.target

[Service]
Type=simple
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
DynamicUser=true
EnvironmentFile=/etc/default/shadowsocks-libev
LimitNOFILE=32768
ExecStart=/usr/bin/ss-server -c $CONFFILE $DAEMON_ARGS

[Install]
WantedBy=multi-user.target

其中 $CONFFILE/etc/default/shadowsocks-libev 中定义, 默认值为 /etc/shadowsocks-libev/config.json.

客户端

我们可以拷贝一份 /lib/systemd/system/shadowsocks-libev.service 重命名为 /lib/systemd/system/shadowsocks-libev-local.service 作为客户端配置, 然后修改启动命令即可.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#  This file is part of shadowsocks-libev.
#
#  Shadowsocks-libev is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 3 of the License, or
#  (at your option) any later version.
#
#  This file is default for Debian packaging. See also
#  /etc/default/shadowsocks-libev for environment variables.

[Unit]
Description=Shadowsocks-libev Default Server Service
Documentation=man:shadowsocks-libev(8)
After=network-online.target

[Service]
Type=simple
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
DynamicUser=true
EnvironmentFile=/etc/default/shadowsocks-libev
LimitNOFILE=32768
ExecStart=/usr/bin/ss-local -c /home/jarvis/tools/ssconfig/config.json

[Install]
WantedBy=multi-user.target

相比于服务端的配置, 我们把 ExecStart 的命令修改为了客户端命令 /usr/bin/ss-local -c /home/jarvis/tools/ssconfig/config.json.

保存后启用, 启动, 查看状态:

1
2
3
4
5
6
7
# 禁用服务端
sudo systemctl disable shadowsocks-libev.service

# 启用客户端
sudo systemctl enable shadowsocks-libev-local.service
sudo systemctl start shadowsocks-libev-local.service
sudo systemctl status shadowsocks-libev-local.service

2.3 rc-local 服务

rc-local 服务是添加用户级别的开机启动项的. 可以把完整开机后才需要启动的命令放在 /etc/rc.local 文件中, 然后通过该服务来启动这些命令.

该开机启动服务一般默认会存在于 /lib/systemd/system/rc-local.service, 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#  SPDX-License-Identifier: LGPL-2.1+
#
#  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=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
RemainAfterExit=no
GuessMainPID=no

#这一段原文件没有,需要自己添加
[Install]
WantedBy=multi-user.target

可以看到该服务执行的命令就是 /etc/rc.local start. 所以我们只需要把需要开机后执行的命令放在 /etc/rc.local 文件中就好了.

/etc/rc.local 文件可能不存在, 需要自己创建, 并赋予可执行权限:

1
sudo chmod +x /etc/rc.local

上一篇 GPT 分区设置

Content