#前言

上次说的:改天一定看如何把自己的代码做成service!!!!,这次来实现了,碰巧用到了。

#好处

做成系统的service之后,可以系统帮你维护,服务意外退出也会帮你重启,这里看我已经做好的例子:

1
2
3
4
5
6
7
onns@onns-desktop:~$ ps -ef | grep ng
root 39 2 0 18:15 ? 00:00:00 [khungtaskd]
avahi 559 1 0 18:15 ? 00:00:03 avahi-daemon: running [onns-desktop.local]
root 680 1 0 18:15 ? 00:00:08 /home/onns/Desktop/ngrok -config /home/onns/Desktop/ngrok.cfg start win ssh
onns 36635 1 0 18:31 ? 00:00:00 /usr/bin/gnome-keyring-daemon --daemonize --login
onns 36643 19483 0 18:31 pts/1 00:00:00 grep --color=auto ng
onns@onns-desktop:~$ sudo kill 680

680是我随系统启动的进程 ID,然后我把这个进程关闭了。

1
2
3
4
5
6
onns@onns-desktop:~$ ps -ef | grep ng
root 39 2 0 18:15 ? 00:00:00 [khungtaskd]
avahi 559 1 0 18:15 ? 00:00:04 avahi-daemon: running [onns-desktop.local]
root 37616 1 6 18:31 ? 00:00:00 /home/onns/Desktop/ngrok -config /home/onns/Desktop/ngrok.cfg start win ssh
onns 38015 1 0 18:31 ? 00:00:00 /usr/bin/gnome-keyring-daemon --daemonize --login
onns 38023 37825 0 18:31 pts/1 00:00:00 grep --color=auto ng

系统自动帮我启动了,换了一个进程号37616

第二个好处也在前面说了,就是可以开机自启!配合着 bios 主板设置的通电开机,可以保证比如实验室突然断电了之后,再次来电之后电脑可以自动开机,寒假回家也不用担心实验室突然断电了!

#配置 service

之前一直觉得配置起来是一件很麻烦的事情,所以一直没弄,没想到原来这么简单!

#查看根进程

所谓的根进程,就是 Linux 系统启动后的第一个进程,PID是 1。之前是init.d,后面大家都推荐用systemd,这两个有两套不同的命令,要先看一下是哪个:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
onns@onns-desktop:~/Desktop$ pstree
systemd─┬─ModemManager───2*[{ModemManager}]
├─NetworkManager───2*[{NetworkManager}]
├─accounts-daemon───2*[{accounts-daemon}]
├─avahi-daemon───avahi-daemon
├─bluetoothd
├─cron
├─cups-browsed───2*[{cups-browsed}]
├─cupsd
├─dbus-daemon
├─7*[gdm-session-wor───2*[{gdm-session-wor}]]
├─gdm3─┬─gdm-session-wor─┬─gdm-wayland-ses─┬─dbus-run-sessio─┬─dbus-daemon
│ │ │ │ └─gnome-session-b───4*[{gnome-session-b}]
│ │ │ └─2*[{gdm-wayland-ses}]
│ │ └─2*[{gdm-session-wor}]
│ └─3*[{gdm3}]
├─hciattach
├─irqbalance───{irqbalance}
├─2*[kerneloops]
├─networkd-dispat
├─ngrok───5*[{ngrok}]
├─polkitd───2*[{polkitd}]
├─rsyslogd───3*[{rsyslogd}]
├─rtkit-daemon───2*[{rtkit-daemon}]
├─snapd───17*[{snapd}]
├─sshd───sshd───bash───pstree
├─sshd
├─switcheroo-cont───2*[{switcheroo-cont}]
├─systemd─┬─(sd-pam)
│ ├─dbus-daemon
│ ├─goa-daemon───3*[{goa-daemon}]
│ ├─goa-identity-se───2*[{goa-identity-se}]
│ ├─gvfs-afc-volume───3*[{gvfs-afc-volume}]
│ ├─gvfs-goa-volume───2*[{gvfs-goa-volume}]
│ ├─gvfs-gphoto2-vo───2*[{gvfs-gphoto2-vo}]
│ ├─gvfs-mtp-volume───2*[{gvfs-mtp-volume}]
│ ├─gvfs-udisks2-vo───3*[{gvfs-udisks2-vo}]
│ ├─gvfsd───2*[{gvfsd}]
│ ├─gvfsd-fuse───5*[{gvfsd-fuse}]
│ ├─tracker-miner-f───6*[{tracker-miner-f}]
│ └─tracker-store───4*[{tracker-store}]
├─systemd─┬─(sd-pam)
│ ├─dbus-daemon
│ ├─goa-daemon───3*[{goa-daemon}]
│ ├─goa-identity-se───2*[{goa-identity-se}]
│ ├─gvfs-afc-volume───3*[{gvfs-afc-volume}]
│ ├─gvfs-goa-volume───2*[{gvfs-goa-volume}]
│ ├─gvfs-gphoto2-vo───2*[{gvfs-gphoto2-vo}]
│ ├─gvfs-mtp-volume───2*[{gvfs-mtp-volume}]
│ ├─gvfs-udisks2-vo───3*[{gvfs-udisks2-vo}]
│ ├─gvfsd───2*[{gvfsd}]
│ ├─gvfsd-fuse───5*[{gvfsd-fuse}]
│ ├─gvfsd-metadata───2*[{gvfsd-metadata}]
│ └─tracker-miner-f───4*[{tracker-miner-f}]
├─systemd-journal
├─systemd-logind
├─systemd-resolve
├─systemd-timesyn───{systemd-timesyn}
├─systemd-udevd
├─udisksd───4*[{udisksd}]
├─unattended-upgr───{unattended-upgr}
├─upowerd───2*[{upowerd}]
├─whoopsie───2*[{whoopsie}]
└─wpa_supplicant

一般新系统都是systemd,就以它为例了。

#创建 service 文件

service可以放在/etc/systemd/system/目录中:

1
2
onns@onns-desktop:~/Desktop$ cd /etc/systemd/system/
onns@onns-desktop:/etc/systemd/system$ sudo vi ngrok.service

新建了一个名为ngrok.service的服务,这个取决于自己的服务名字咯,可以ls看一下,你会发现一些常用的比如远程连接的sshd.service都在这个文件夹里。

填写内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=ngrok
After=network.target

[Service]
ExecStart=/home/onns/Desktop/ngrok -config /home/onns/Desktop/ngrok.cfg start win ssh
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
IgnoreSIGPIPE=true
Restart=always
RestartSec=3
Type=simple

[Install]
WantedBy=multi-user.target

这里也有很多我不知道的参数,不过目前我还用不上,实在没时间去挨个了解了,主要配置DescriptionExecStart就行。

Description:就是给人看的,告诉别人你这个service是啥。
After:依赖服务,就是这个服务必须在哪些service运行之后才能运行。
ExecStart:就执行脚本咯。这个是重点!
Restart:重启,就是上面说的,意外终止由系统帮你重启。
RestartSec:每多少秒尝试一次。

#配置

其实这个时候就可以启动你创建好的服务了:

1
2
3
4
5
6
7
onns@onns-desktop:/etc/systemd/system$ systemctl start ngrok.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to start 'ngrok.service'.
Authenticating as: onns,,, (onns)
Password:
==== AUTHENTICATION COMPLETE ===
Warning: The unit file, source configuration file or drop-ins of ngrok.service changed on disk. Run 'systemctl daemon-reload' to reload units.

需要密码验证,然后有一句特殊提示:

Warning: The unit file, source configuration file or drop-ins of ngrok.service changed on disk. Run ‘systemctl daemon-reload’ to reload units.

所以其实要重新加载一下(因为你毕竟添加了一个service):

1
2
3
4
5
6
onns@onns-desktop:/etc/systemd/system$ systemctl daemon-reload
==== AUTHENTICATING FOR org.freedesktop.systemd1.reload-daemon ===
Authentication is required to reload the systemd state.
Authenticating as: onns,,, (onns)
Password:
==== AUTHENTICATION COMPLETE ===

然后就可以开启服务了:

1
2
3
4
5
6
onns@onns-desktop:/etc/systemd/system$ systemctl start ngrok.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to start 'ngrok.service'.
Authenticating as: onns,,, (onns)
Password:
==== AUTHENTICATION COMPLETE ===

然后查看这个服务的状态:

1
2
3
4
5
6
7
8
9
10
onns@onns-desktop:/etc/systemd/system$ systemctl status ngrok.service
● ngrok.service - ngrok
Loaded: loaded (/etc/systemd/system/ngrok.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-12-14 18:31:42 CST; 30min ago
Main PID: 37616 (ngrok)
Tasks: 6 (limit: 8967)
CGroup: /system.slice/ngrok.service
└─37616 /home/onns/Desktop/ngrok -config /home/onns/Desktop/ngrok.cfg start win ssh

12月 14 18:31:42 onns-desktop systemd[1]: Started ngrok.

博客的代码是没有颜色的,可以凑合着看一下。

然后最重要的一步是开启开机启动

1
2
3
4
5
6
7
8
9
10
11
onns@onns-desktop:/etc/systemd/system$ systemctl enable ngrok.service
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-unit-files ===
Authentication is required to manage system service or unit files.
Authenticating as: onns,,, (onns)
Password:
==== AUTHENTICATION COMPLETE ===
==== AUTHENTICATING FOR org.freedesktop.systemd1.reload-daemon ===
Authentication is required to reload the systemd state.
Authenticating as: onns,,, (onns)
Password:
==== AUTHENTICATION COMPLETE ===

#总结

1
2
3
4
5
6
7
8
9
10
11
12
13
# 制作好 .service 文件之后

# 重载一下service文件
systemctl daemon-reload

# 开启服务开机启动
systemctl enable ngrok.service

# 开启服务
systemctl start ngrok.service

# 查看服务状态
systemctl status ngrok.service

#参考链接

看了好多链接,发现都不是很通用,到时候最好去看看别人怎么写的,然后 copy 一下