systemd 是 linux 中常見的服務管理工具,讓我們可以很方便的建立和管理服務,能夠讓服務自動啟動、重啟、定時執行等。
在 /etc/systemd/system 資料夾中建立一個 my-test.service 檔案:
上面設定檔的意思是執行 /home/ruyut/run.sh 指令,如果執行失敗後間隔 30 秒再次執行。
接下來要給予檔案權限,使檔案可以執行:
啟動服務:
註: 服務執行後會失敗,因為在這裡我們並沒有建立 /home/ruyut/run.sh 檔案,服務會因為找不到要執行的指令檔而發生錯誤,但是間隔 30 秒後就會自動再次執行。
等待幾分鐘後使用下面的指令查看執行日誌:
可以發現確實執行後失敗,並且 30 秒後會自動再次執行
假設我們依照服務設定檔中的路徑在 /home/ruyut 建立了 run.sh 檔案:
等待一分鐘後再次查看 log 就會發現成功執行,並且不會再自動執行了。
代表我們的設定檔內容不足,還缺少 Install 區塊:
等等,WantedBy 設定值的 multi-user.target 參數是什麼意思?還有哪些可以用的參數?
筆者研究了一番後將常用設定值整理如下:
重新讀取服務設定檔:
檢查服務狀態:
關閉服務:
取消開機自動啟動服務:
參考資料:
RedHat - Chapter 10. Managing Services with systemd
最簡單 service 檔案
我們會建立副檔名為 .service 的檔案來定義服務,副檔名沒有一定需要 .service ,但是不同的副檔名通常對應不同功能的服務,這裡直接使用 .service 做示範。在 /etc/systemd/system 資料夾中建立一個 my-test.service 檔案:
[Service]
ExecStart=/bin/bash /home/ruyut/run.sh
Restart=on-failure
RestartSec=30
上面設定檔的意思是執行 /home/ruyut/run.sh 指令,如果執行失敗後間隔 30 秒再次執行。
接下來要給予檔案權限,使檔案可以執行:
sudo chmod +x /etc/systemd/system/my-test.service
啟動服務:
sudo systemctl start my-test.service
註: 服務執行後會失敗,因為在這裡我們並沒有建立 /home/ruyut/run.sh 檔案,服務會因為找不到要執行的指令檔而發生錯誤,但是間隔 30 秒後就會自動再次執行。
等待幾分鐘後使用下面的指令查看執行日誌:
journalctl -u my-test.service
可以發現確實執行後失敗,並且 30 秒後會自動再次執行
journalctl -u my-test.service
May 14 15:27:42 ruyut systemd[1]: Started my-test.service.
May 14 15:27:42 ruyut bash[52621]: /bin/bash: /home/ruyut/run.sh: No such file or directory
May 14 15:27:42 ruyut systemd[1]: my-test.service: Main process exited, code=exited, status=127/n/a
May 14 15:27:42 ruyut systemd[1]: my-test.service: Failed with result 'exit-code'.
May 14 15:28:12 ruyut systemd[1]: my-test.service: Scheduled restart job, restart counter is at 1.
May 14 15:28:12 ruyut systemd[1]: Stopped my-test.service.
May 14 15:28:12 ruyut systemd[1]: Started my-test.service.
May 14 15:28:12 ruyut bash[53418]: /bin/bash: /home/ruyut/run.sh: No such file or directory
May 14 15:28:12 ruyut systemd[1]: my-test.service: Main process exited, code=exited, status=127/n/a
May 14 15:28:12 ruyut systemd[1]: my-test.service: Failed with result 'exit-code'.
May 14 15:28:43 ruyut systemd[1]: my-test.service: Scheduled restart job, restart counter is at 2.
May 14 15:28:43 ruyut systemd[1]: Stopped my-test.service.
May 14 15:28:43 ruyut systemd[1]: Started my-test.service.
May 14 15:28:43 ruyut bash[54214]: /bin/bash: /home/ruyut/run.sh: No such file or directory
May 14 15:28:43 ruyut systemd[1]: my-test.service: Main process exited, code=exited, status=127/n/a
May 14 15:28:43 ruyut systemd[1]: my-test.service: Failed with result 'exit-code'.
假設我們依照服務設定檔中的路徑在 /home/ruyut 建立了 run.sh 檔案:
#!/bin/bash
echo "$(date)"
等待一分鐘後再次查看 log 就會發現成功執行,並且不會再自動執行了。
journalctl -u my-test.service
May 14 15:38:17 ruyut systemd[1]: Started my-test.service.
May 14 15:38:17 ruyut bash[69255]: /bin/bash: /home/ruyut/run.sh: No such file or directory
May 14 15:38:17 ruyut systemd[1]: my-test.service: Main process exited, code=exited, status=127/n/a
May 14 15:38:17 ruyut systemd[1]: my-test.service: Failed with result 'exit-code'.
May 14 15:38:47 ruyut systemd[1]: my-test.service: Scheduled restart job, restart counter is at 22.
May 14 15:38:47 ruyut systemd[1]: Stopped my-test.service.
May 14 15:38:47 ruyut systemd[1]: Started my-test.service.
May 14 15:38:47 ruyut bash[70087]: Tue May 14 03:38:47 PM UTC 2024
May 14 15:38:47 ruyut systemd[1]: my-test.service: Deactivated successfully.
自動執行服務
上面我們建立的服務需要手動啟動,如果想要開機自動執行的話會出現下列錯誤:
sudo systemctl enable my-test.service
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.
代表我們的設定檔內容不足,還缺少 Install 區塊:
[Service]
ExecStart=/bin/bash /home/ruyut/run.sh
Restart=on-failure
RestartSec=30
[Install]
WantedBy=multi-user.target
等等,WantedBy 設定值的 multi-user.target 參數是什麼意思?還有哪些可以用的參數?
筆者研究了一番後將常用設定值整理如下:
- basic.target: 代表 Linux 已啟動,基礎服務可以使用的狀態
- multi-user.target: 代表 Linux 已啟動,啟動狀態已經達到可以讓多個使用者使用
- graphical.target: 代表 Linux 已啟動,啟動狀態已經達到可以使用圖形化使用者介面(註:在沒有安裝圖形化介面的 Linux 中使用這個會在 log 中附加一條警告,因為沒有圖形化介面可以使用)
- network.target: 代表網路功能已啟動
- network-online.target: 代表網路功能啟動成功
sudo systemctl enable my-test.service
其他常用指令
使用跟隨模式持續顯示服務的日誌:
journalctl -u my-test.service -f
重新讀取服務設定檔:
sudo systemctl daemon-reload
檢查服務狀態:
sudo systemctl status my-test.service
關閉服務:
sudo systemctl stop my-test.service
取消開機自動啟動服務:
sudo systemctl disable my-test.service
其他設定值範例
[Unit]
Description=這是示範用的 service 檔案
[Service]
ExecStart=/bin/bash /home/ruyut/run.sh
Restart=always
RestartSec=10
[Install]
WantedBy=network-online.target
參考資料:
RedHat - Chapter 10. Managing Services with systemd
感謝教學~
回覆刪除