
我有一個帶有“while true”循環的腳本。我想每分鐘從 cron 運行該腳本,這樣當進程被終止(或失敗 - 無論為什麼) cron 時將再次運行該腳本。
但是當我檢查時,ps -aef --forest
我的進程是由/usr/sbin/CROND -n
.這對 cron 或系統來說不是壞事嗎?或者也許我應該採取不同的做法?
答案1
也許一個簡短的服務範例systemd
就可以了。
這是我們的無限腳本、位置/path/to/infinite_script
、可執行位元集:
#!/bin/bash
while ((1)) ; do
date >> /tmp/infinite_date
sleep 2
done
不,我們需要定義一個服務文件:
[Unit]
#just what it does
Description= infinite date service
[Service]
#not run by root, but by me
User=fiximan
#we assume the full service as active one the script was started
Type=simple
#where to find the executable
ExecStart=/path/to/infinite_script
#what you want: make sure it always is running
Restart=always
[Install]
#which service wants this to run - default.target is just it is loaded by default
WantedBy=default.target
並將其放入/etc/systemd/system/infinite_script.service
現在載入並啟動服務(以 root 身分):
systemctl enable infinite_script.service
systemctl start infinite_script.service
該服務現在正在運行,我們可以檢查其狀態
systemctl status infinite_script.service
● infinite_script.service - infinite date service
Loaded: loaded (/etc/systemd/system/infinite_script.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2019-05-28 14:18:52 CEST; 1min 33s ago
Main PID: 7349 (infinite_script)
Tasks: 2 (limit: 4915)
Memory: 1.5M
CGroup: /system.slice/infinite_script.service
├─7349 /bin/bash /path/to/infinite_script
└─7457 sleep 2
Mai 28 14:18:52 <host> systemd[1]: Started infinite date service.
現在,如果您終止腳本(kill 7349
-主 PID)並再次檢查狀態:
● infinite_script.service - infinite date service
Loaded: loaded (/etc/systemd/system/infinite_script.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2019-05-28 14:22:21 CEST; 12s ago
Main PID: 7583 (infinite_script)
Tasks: 2 (limit: 4915)
Memory: 1.5M
CGroup: /system.slice/infinite_script.service
├─7583 /bin/bash /path/to/infinite_script
└─7606 sleep 2
Mai 28 14:22:21 <host> systemd[1]: Started infinite date service.
因此請注意它是如何使用新的 PID 立即重新啟動的。
並檢查輸出的文件所有權:
ls /tmp/infinite/date
-rw-r--r-- 1 fiximan fiximan 300 Mai 28 14:31 infinite_date
因此腳本由服務文件中設定的正確使用者執行。
當然,您可以停止並停用該服務:
systemctl stop infinite_script.service
systemctl disable infinite_script.service
編輯:
更多細節:使用者的個人服務可以(預設)放置在 中$HOME/.config/systemd/user/
並進行相應管理systemctl --user <commands>
。就像個人 crontab 一樣,不需要 root。
答案2
畝。
cron 是不適合這項工作的工具。
正確的工具是服務經理,此外也融入了服務終止時自動重新啟動的想法。 (並非所有人都這樣做。)此類服務管理員包括:
- 丹·伯恩斯坦的守護程式工具
- 亞當桑普森的芙烈特
- 布魯斯·岡特的daemontools-encore
- 洛朗·貝爾科特s6
- 格里特·佩普的運行
- 韋恩馬歇爾的罪犯
- launchd(僅限 MacOS)
- systemd(僅限 Linux)
- fscd(僅限 FreeBSD)
- 監督者
- 我的開胃菜
建立一個適合服務管理員的服務定義,執行無限循環腳本,然後新增它。對於某些服務管理器來說,這只是一個run
執行無限循環腳本的小程式(通常本身就是一個腳本)。服務管理員負責啟動、監視和自動重新啟動。
可以輕鬆地使用幾個服務管理器來進行每用戶服務管理以及系統範圍內的服務管理,並且可以將其設置為作為自己的帳戶運行的服務的每個用戶服務定義,並且可以在沒有超級用戶的情況下進行管理權限(管理系統範圍的服務所需)。
進一步閱讀
- 約書亞‧汀伯曼 (2012-12-29)。過程監督:已解決的問題。
- 拉里·杜利特爾 (2005-06-23)。Unix 守護程式基礎。
- 喬納森·德博因·波拉德 (2015)。守護程式工具家族。經常給的答案。
- 確保進程始終運行
- linux/CentOS 中如何在進程被殺死時自動重新啟動進程
答案3
@菲利克斯JN
警告:開啟 selinux 可能會阻止您的腳本運行。為了讓它發揮作用,我
將其移至
/usr/local/bin
(這是 selinux 支援的資料夾)並進行對應的編輯
/etc/systemd/system/infinite_script.service
更正ExecStart
運行
sudo restorecon -rv /usr/local/bin
以將此資訊獲取到 selinux 並systemctl daemon-reload
終於跑到重新啟動服務
systemctl start infinite_script.service