submit tech/20180502 Writing Systemd Services for Fun and Profit.md

This commit is contained in:
songshunqiang 2018-05-16 20:17:40 +08:00
parent b648f6095c
commit 529d3fc0a8
2 changed files with 106 additions and 110 deletions

View File

@ -1,110 +0,0 @@
pinewall translating
Writing Systemd Services for Fun and Profit
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/minetest.png?itok=Houi9zf9)
Let's say you want to run a games server, a server that runs [Minetest][1], a very cool and open source mining and crafting sandbox game. You want to set it up for your school or friends and have it running on a server in your living room. Because, you know, if thats good enough for the kernel mailing list admins, then it's good enough for you.
However, you soon realize it is a chore to remember to run the server every time you switch your computer on and a nuisance to power down safely when you want to switch off.
First, you have to run the server as a daemon:
```
minetest --server &
```
Take note of the PID (you'll need it later).
Then you have to tell your friends the server is up by emailing or messaging them. After that you can start playing.
Suddenly it is 3 am. Time to call it a day! But you can't just switch off your machine and go to bed. First, you have to tell the other players the server is coming down, locate the bit of paper where you wrote the PID we were talking about earlier, and kill the Minetest server gracefully...
```
kill -2 <PID>
```
...because just pulling the plug is a great way to end up with corrupted files. Then and only then can you power down your computer.
There must be a way to make this easier.
### Systemd Services to the Rescue
Let's start off by making a systemd service you can run (manually) as a regular user and build up from there.
Services you can run without admin privileges live in _~/.config/systemd/user/_ , so start by creating that directory:
```
cd
mkdir -p ~/.config/systemd/user/
```
There are several types of systemd _units_ (the formal name of systemd scripts), such as _timers_ , _paths_ , and so on; but what you want is a service. Create a file in _~/.config/systemd/user/_ called _minetest.service_ and open it with your text editor and type the following into it:
```
# minetest.service
[Unit]
Description= Minetest server
Documentation= https://wiki.minetest.net/Main_Page
[Service]
Type= simple
ExecStart= /usr/games/minetest --server
```
Notice how units have different sections: The `[Unit]` section is mainly informative. It contains information for users describing what the unit is and where you can read more about it.
The meat of your script is in the `[Service]` section. Here you start by stating what kind of service it is using the `Type` directive. [There are several types][2] of service. If, for example, the process you run first sets up an environment and then calls in another process (which is the main process) and then exits, you would use the `forking` type; if you needed to block the execution of other units until the process in your unit finished, you would use `oneshot`; and so on.
None of the above is the case for the Minetest server, however. You want to start the server, make it go to the background, and move on. This is what the `simple` type does.
Next up is the `ExecStart` directive. This directive tells systemd what program to run. In this case, you are going to run `minetest` as headless server. You can add options to your executables as shown above, but you can't chain a bunch of Bash commands together. A line like:
```
ExecStart: lsmod | grep nvidia > videodrive.txt
```
Would not work. If you need to chain Bash commands, it is best to wrap them in a script and execute that.
Also notice that systemd requires you give the full path to the program. So, even if you have to run something as simple as _ls_ you will have to use `ExecStart= /bin/ls`.
There is also an `ExecStop` directive that you can use to customize how your service should be terminated. We'll be talking about this directive more in part two, but for now you must know that, if you don't specify an `ExecStop`, systemd will take it on itself to finish the process as gracefully as possible.
There is a full list of directives in the _systemd.directives_ man page or, if you prefer, [you can check them out on the web][3] and click through to see what each does.
Although only 6 lines long, your _minetest.service_ is already a fully functional systemd unit. You can run it by executing
```
systemd --user start minetest
```
And stop it with
```
systemd --user stop minetest
```
The `--user` option tells systemd to look for the service in your own directories and to execute the service with your user's privileges.
That wraps up this part of our server management story. In part two, well go beyond starting and stopping and look at how to send emails to players, alerting them of the servers availability. Stay tuned.
Learn more about Linux through the free ["Introduction to Linux" ][4]course from The Linux Foundation and edX.
--------------------------------------------------------------------------------
via: https://www.linux.com/blog/learn/intro-to-linux/2018/5/writing-systemd-services-fun-and-profit
作者:[Paul Brown][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/bro66
[1]:https://www.minetest.net/
[2]:http://man7.org/linux/man-pages/man5/systemd.service.5.html
[3]:http://man7.org/linux/man-pages/man7/systemd.directives.7.html
[4]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux

View File

@ -0,0 +1,106 @@
编写有趣且有价值的 Systemd 服务
======
![](https://www.linux.com/sites/lcom/files/styles/rendered_file/public/minetest.png?itok=Houi9zf9)
让我们假设你希望搭建一个游戏服务器,运行 [Minetest][1] 这款非常酷、开源的、以采集 & 合成为主题的沙盒游戏。你希望将游戏运行在位于客厅的服务器中,以便搭建完成后可供你的学校或朋友使用。考虑到内核邮件列表管理就是通过这种方式完成的,那么对你来说也是足够的。
但你很快发现每次开机之后需要启动服务器,每次关机之前需要安全地关闭服务器,十分繁琐和麻烦。
最初,你可能用守护进程的方式运行服务器:
```
minetest --server &
```
记住进程 PID 以便后续使用。
接着,你还需要通过邮件或短信的方式将服务器已经启动的信息告知你的朋友。然后你就可以开始游戏了。
转眼之间,已经凌晨三点,今天的战斗即将告一段落。但在你关闭主机、睡个好觉之前,还需要做一些操作。首先,你需要通知其它玩家服务器即将关闭,找到记录我们之前提到的 PID 的纸条,然后友好地关闭 Minetest 服务器。
```
kill -2 <PID>
```
因为直接关闭主机电源很可能导致文件损坏。下一步也是最后一步,关闭主机电源。
一定有方法能让事情变得更简单。
### 让 Systemd 服务拯救你
让我们从构建一个普通用户可以(手动)运行的 systemd 服务开始,然后再逐步增加内容。
不需要管理员权限即可运行的服务位于 _~/.config/systemd/user/_,故首先需要创建这个目录:
```
cd
mkdir -p ~/.config/systemd/user/
```
有很多类型的 systemd _units_ (曾经叫做 systemd 脚本),包括 _timers__paths_ 等,但我们这里关注的是 service 类型。在 _~/.config/systemd/user/_ 目录中创建 _minetest.service_ 文件,使用文本编辑器打开并输入如下内容:
```
# minetest.service
[Unit]
Description= Minetest server
Documentation= https://wiki.minetest.net/Main_Page
[Service]
Type= simple
ExecStart= /usr/games/minetest --server
```
可以看到 units 中包含不同的段,其中 `[Unit]` 段主要为用户提供信息,给出 unit 的描述及如何获得更多相关文档。
脚本核心位于 `[Service]` 段,首先使用 `Type` 指令确定服务类型。服务[有多种类型][2],下面给出两个示例。如果你运行的进程设置环境变量、调用另外一个进程(主进程)、退出运行,那么你应该使用的服务类型为 `forking`。如果你希望在你的 unit 对应进程结束运行前阻断其他 units 运行,那么你应该使用的服务类型为 `oneshot`
但 Minetest 服务器的情形与上面两种都不同,你希望启动服务器并使其在后台持续运行;这种情况下应该使用 `simple` 类型。
下面来看 `ExecStart` 指令,它给出 systemd 需要运行的程序。在本例中,你希望在后台运行 `minetest` 服务器。如上所示,你可以在可执行程序后面添加参数,但不能将一系列 Bash 命令通过管道连接起来。下面给出的例子无法工作:
```
ExecStart: lsmod | grep nvidia > videodrive.txt
```
如果你需要将 Bash 命令通过管道连接起来,可以将其封装到一个脚本中,然后运行该脚本。
还需要注意一点systemd 要求你给出程序的完整路径。故如果你想使用 `simeple` 类型运行类似 _ls_ 的命令,你需要使用 `ExecStart= /bin/ls`
另外还有 `ExecStop` 指令用于定制服务终止的方式。我们会在第二部分讨论这个指令,但你要了解,如果你没有指定 `ExecStop`systemd 会帮你尽可能友好地终止进程。
_systemd.directives_ 的帮助页中包含完整指令列表,另外你可以在[网站][3]上找到同样的列表,点击即可查看每个指令的具体信息。
虽然只有 6 行,但你的 _minetest.service_ 已经是一个有完整功能的 systemd unit。执行如下命令启动服务
```
systemd --user start minetest
```
执行如下命令终止服务
```
systemd --user stop minetest
```
选项 `--user` 告知 systemd 在你的本地目录中检索服务并用你的用户权限执行服务。
我们的服务器管理故事到此完成了第一部分。在第二部分,我们将在启动和终止服务的基础上,学习如何给用户发邮件、告知用户服务器的可用性。敬请期待。
可以通过 Linux 基金会和 edX 的免费课程 [Linux 入门][4]学习更多 Linux 知识。
--------------------------------------------------------------------------------
via: https://www.linux.com/blog/learn/intro-to-linux/2018/5/writing-systemd-services-fun-and-profit
作者:[Paul Brown][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[pinewall](https://github.com/pinewall)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://www.linux.com/users/bro66
[1]:https://www.minetest.net/
[2]:http://man7.org/linux/man-pages/man5/systemd.service.5.html
[3]:http://man7.org/linux/man-pages/man7/systemd.directives.7.html
[4]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux