編寫有趣且有價值的 Systemd 服務
讓我們假設你希望搭建一個遊戲伺服器,運行 Minetest 這款非常酷、開源的,以採集 & 合成為主題的沙盒遊戲。你希望將遊戲運行在位於客廳的伺服器中,以便搭建完成後可供你的學校或朋友使用。你知道內核郵件列表的管理就不過就是如此,那麼對你來說也是足夠的。
但你很快發現每次開機之後需要啟動服務進程,每次關機之前需要安全地關閉伺服器,十分繁瑣和麻煩。
最初,你可能用守護進程的方式運行伺服器:
minetest --server &
記住進程 PID 以便後續使用。
接著,你還需要通過郵件或簡訊的方式將伺服器已經啟動的信息告知你的朋友。然後你就可以開始遊戲了。
轉眼之間,已經凌晨三點,今天的戰鬥即將告一段落。但在你關閉主機、睡個好覺之前,還需要做一些操作。首先,你需要通知其它玩家伺服器即將關閉,找到記錄我們之前提到的 PID 的紙條,然後友好地關閉 Minetest 服務進程。
kill -2 <PID>
這是因為直接關閉主機電源很可能導致文件損壞。下一步也是最後一步,關閉主機電源。
一定有方法能讓事情變得更簡單。
讓 Systemd 服務拯救你
讓我們從構建一個普通用戶可以(手動)運行的 systemd 服務開始,然後再逐步增加內容。
不需要管理員許可權即可運行的服務位於 ~/.config/systemd/user/
,故首先需要創建這個目錄:
cd
mkdir -p ~/.config/systemd/user/
有很多類型的 systemd 單元 (曾經叫做 systemd 腳本),包括「計時器」和「路徑」等,但我們這裡關注的是「服務」類型。在 ~/.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
可以看到該單元中包含不同的段,其中 [Unit]
段主要為用戶提供信息,給出該單元的描述及如何獲得更多相關文檔。
腳本核心位於 [Service]
段,首先使用 Type
指令確定服務類型。服務有多種類型,下面給出兩個示例。如果你運行的進程設置環境變數、調用另外一個進程(主進程)、退出運行,那麼你應該使用的服務類型為 forking
。如果你希望在你的單元對應進程結束運行前阻斷其他單元運行,那麼你應該使用的服務類型為 oneshot
。
但 Minetest 伺服器的情形與上面兩種都不同,你希望啟動伺服器並使其在後台持續運行;這種情況下應該使用 simple
類型。
下面來看 ExecStart
指令,它給出 systemd 需要運行的程序。在本例中,你希望在後台運行 minetest
伺服器。如上所示,你可以在可執行程序後面添加參數,但不能將一系列 Bash 命令通過管道連接起來。下面給出的例子無法工作:
ExecStart: lsmod | grep nvidia > videodrive.txt
如果你需要將 Bash 命令通過管道連接起來,可以將其封裝到一個腳本中,然後運行該腳本。
還需要注意一點,systemd 要求你給出程序的完整路徑。故如果你想使用 simple
類型運行類似 ls
的命令,你需要使用 ExecStart= /bin/ls
。
另外還有 ExecStop
指令用於定製服務終止的方式。我們會在第二部分討論這個指令,但你要了解,如果你沒有指定 ExecStop
,systemd 會幫你儘可能友好地終止進程。
systemd.directives
的幫助頁中包含完整指令列表,另外你可以在該網站上找到同樣的列表,點擊即可查看每個指令的具體信息。
雖然只有 6 行,但你的 minetest.service
已經是一個有完整功能的 systemd 單元。執行如下命令啟動服務:
systemd --user start minetest
執行如下命令終止服務:
systemd --user stop minetest
選項 --user
告知 systemd 在你的本地目錄中檢索服務並用你的用戶許可權執行服務。
我們的伺服器管理故事到此完成了第一部分。在第二部分,我們將在啟動和終止服務的基礎上,學習如何給用戶發郵件、告知用戶伺服器的可用性。敬請期待。
可以通過 Linux 基金會和 edX 的免費課程 「Linux 入門」學習更多 Linux 知識。
via: https://www.linux.com/blog/learn/intro-to-linux/2018/5/writing-systemd-services-fun-and-profit
作者:Paul Brown 選題:lujun9972 譯者:pinewall 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive