透過自己寫 Systemd Unit Files 方式來取代傳統的 (crontab) cron table 啟動程式.
測試環境 CentOS 8 x86_64 (虛擬機)
寫了一支會定期 60 秒寫入時間資料到檔案的 c++ 程式.
[root@localhost ~]# vi test.cpp #include <fstream> #include <iostream> #include <chrono> #include <ctime> #include <unistd.h> using namespace std; int main() { while(true) { ofstream myFile_Handler; // File Open myFile_Handler.open("/tmp/1.txt", std::ios_base::app); auto timenow = chrono::system_clock::to_time_t(chrono::system_clock::now()); // Write to the file myFile_Handler << ctime(&timenow) << endl; // File Close myFile_Handler.close(); // Sleep sleep(60); } }
編譯成可執行檔.
[root@localhost ~]# g++ test.cpp -o test bash: g++: command not found... Install package 'gcc-c++' to provide command 'g++'? [N/y] y
程式放到 /sbin/ 路徑.
[root@localhost ~]# cp test /sbin/
開始編輯 Systemd Unit Files (一般使用者寫的 service 檔案放在 /etc/systemd/system/ ,系統的放在 /usr/lib/systemd/system).
[root@localhost ~]# vi /etc/systemd/system/test.service [Unit] Description=Test Job [Service] Type=simple ExecStart=/sbin/test [Install] WantedBy=multi-user.target
只簡單設定3個區塊
- [unit]
Description=Test Job
Description 敘述該 Systemd Unit Files 目的.
- [Service]
Type=simple ExecStart=/sbin/test
Type=simple – A long-running process that does not background its self and stays attached to the shell.
ExecStart – 指定執行程式. - [Install]
WantedBy=multi-user.target
指定哪一個 runlevel 執行.
啟動服務
[root@localhost ~]# systemctl enable test.service Created symlink /etc/systemd/system/multi-user.target.wants/test.service → /etc/systemd/system/test.service. [root@localhost ~]# systemctl start test.service [root@localhost ~]# systemctl status test.service ● test.service - Test Job Loaded: loaded (/etc/systemd/system/test.service; enabled; vendor preset: disabled) Active: active (running) since Fri 2022-11-25 11:02:40 CST; 7s ago Main PID: 89850 (test) Tasks: 1 (limit: 49322) Memory: 292.0K CGroup: /system.slice/test.service └─89850 /sbin/test Nov 25 11:02:40 localhost.localdomain systemd[1]: Started Test Job.
檢視 /sbin/test (定期 60 秒寫入時間資料到檔案 /tmp/1.txt) 是否有正常執行.
[root@localhost ~]# cat /tmp/1.txt Fri Nov 25 11:02:40 2022 Fri Nov 25 11:03:40 2022 Fri Nov 25 11:04:40 2022
結束測試.
[root@localhost ~]# systemctl stop test.service [root@localhost ~]# systemctl disable test.service Removed /etc/systemd/system/multi-user.target.wants/test.service.
Note:
其中的 type 是最困惱的地方,要選哪一種?
- simple – A long-running process that does not background its self and stays attached to the shell.
- forking – A typical daemon that forks itself detaching it from the process that ran it, effectively backgrounding itself.
- oneshot – A short-lived process that is expected to exit.
- dbus – Like simple, but notification of processes startup finishing is sent over dbus.
- notify – Like simple, but notification of processes startup finishing is sent over inotify.
- idle – Like simple, but the binary is started after the job has been dispatched.
以上的程式是無法使用 type=forking
[root@localhost ~]# vi /etc/systemd/system/test.service [Unit] Description=Test Job [Service] Type=forking ExecStart=/sbin/test
[root@localhost ~]# systemctl daemon-reload [root@localhost ~]# systemctl restart test.service Job for test.service failed because a timeout was exceeded. See "systemctl status test.service" and "journalctl -xe" for details.
[root@localhost ~]# systemctl status test.service ● test.service - Test Job Loaded: loaded (/usr/lib/systemd/system/test.service; static; vendor preset: disabled) Active: failed (Result: timeout) since Wed 2022-09-14 17:59:09 CST; 12s ago Process: 2682 ExecStart=/sbin/test (code=killed, signal=TERM) Main PID: 2654 (code=killed, signal=TERM) 9月 14 17:57:39 localhost.localdomain systemd[1]: Stopping Test Job... 9月 14 17:57:39 localhost.localdomain systemd[1]: test.service: Succeeded. 9月 14 17:57:39 localhost.localdomain systemd[1]: Stopped Test Job. 9月 14 17:57:39 localhost.localdomain systemd[1]: Starting Test Job... 9月 14 17:59:09 localhost.localdomain systemd[1]: test.service: start operation timed out. Terminating. 9月 14 17:59:09 localhost.localdomain systemd[1]: test.service: Failed with result 'timeout'. 9月 14 17:59:09 localhost.localdomain systemd[1]: Failed to start Test Job.
[root@localhost ~]# journalctl -xe -- -- 單位 test.service 已開始啟動。 9月 14 17:59:09 localhost.localdomain systemd[1]: test.service: start operation timed out. Terminating. 9月 14 17:59:09 localhost.localdomain systemd[1]: test.service: Failed with result 'timeout'. -- Subject: Unit failed -- Defined-By: systemd -- Support: https://access.redhat.com/support -- -- The unit test.service has entered the 'failed' state with result 'timeout'. 9月 14 17:59:09 localhost.localdomain systemd[1]: Failed to start Test Job. -- Subject: 單位 test.service 已失敗 -- Defined-By: systemd -- Support: https://access.redhat.com/support -- -- 單位 test.service 已失敗。 -- -- 結果為 failed。
關於 simple 與 forking 使用時機請參考說明 – https://superuser.com/questions/1274901/systemd-forking-vs-simple
- simple
If the service starts and keeps running, and the prompt does not return until you press Control-C or stop the service in some other way. - forking
If the prompt returns but the service keeps running in the background (i.e. the service daemonizes itself on its own).
沒有解決問題,試試搜尋本站其他內容