我有一个带有“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