我有一个带有“while true”循环的脚本。我想每分钟从 cron 运行该脚本,这样当进程被终止(或失败 - 无论为什么)时 cron 将再次运行该脚本。
但是当我检查时,ps -aef --forest
我的进程是由/usr/sbin/CROND -n
. 这对 cron 或系统来说不是坏事吗?或者也许我应该采取不同的做法?
cron 是不适合这项工作的工具。
正确的工具是服务管理器,它还融入了服务终止时自动重新启动的思想。(并非所有人都这样做。)此类服务管理器包括:
创建一个适合服务管理器的服务定义,运行无限循环脚本,然后添加它。对于一些服务管理器来说,这只是一个run
执行无限循环脚本的小程序(通常本身就是一个脚本)。服务管理器负责启动、监视和自动重新启动。
几个服务管理器很容易被用来进行每用户服务管理以及系统范围的服务管理,并且可以将其设置为作为自己的帐户运行的服务的每用户服务定义,并且可以在没有超级用户的情况下进行管理权限(管理系统范围的服务所需)。
也许一个简短的服务示例systemd
就可以了。
这是我们的无限脚本,位置/path/to/infinite_script
、可执行位集:
#!/bin/bash\nwhile ((1)) ; do\n date >> /tmp/infinite_date\n sleep 2\ndone\n
Run Code Online (Sandbox Code Playgroud)\n\n不,我们需要定义一个服务文件:
\n\n[Unit]\n#just what it does\nDescription= infinite date service\n\n[Service]\n#not run by root, but by me\nUser=fiximan\n#we assume the full service as active one the script was started\nType=simple\n#where to find the executable\nExecStart=/path/to/infinite_script\n#what you want: make sure it always is running\nRestart=always\n\n[Install]\n#which service wants this to run - default.target is just it is loaded by default\nWantedBy=default.target\n
Run Code Online (Sandbox Code Playgroud)\n\n并将其放入/etc/systemd/system/infinite_script.service
现在加载并启动服务(以 root 身份):
\n\nsystemctl enable infinite_script.service\nsystemctl start infinite_script.service\n
Run Code Online (Sandbox Code Playgroud)\n\n该服务现在正在运行,我们可以检查其状态
\n\nsystemctl status infinite_script.service\n\n\xe2\x97\x8f infinite_script.service - infinite date service\n Loaded: loaded (/etc/systemd/system/infinite_script.service; enabled; vendor preset: enabled)\n Active: active (running) since Tue 2019-05-28 14:18:52 CEST; 1min 33s ago\n Main PID: 7349 (infinite_script)\n Tasks: 2 (limit: 4915)\n Memory: 1.5M\n CGroup: /system.slice/infinite_script.service\n \xe2\x94\x9c\xe2\x94\x807349 /bin/bash /path/to/infinite_script\n \xe2\x94\x94\xe2\x94\x807457 sleep 2\n\nMai 28 14:18:52 <host> systemd[1]: Started infinite date service.\n
Run Code Online (Sandbox Code Playgroud)\n\n现在如果你杀死脚本(kill 7349
-主 PID)并再次检查状态:
\xe2\x97\x8f infinite_script.service - infinite date service\n Loaded: loaded (/etc/systemd/system/infinite_script.service; enabled; vendor preset: enabled)\n Active: active (running) since Tue 2019-05-28 14:22:21 CEST; 12s ago\n Main PID: 7583 (infinite_script)\n Tasks: 2 (limit: 4915)\n Memory: 1.5M\n CGroup: /system.slice/infinite_script.service\n \xe2\x94\x9c\xe2\x94\x807583 /bin/bash /path/to/infinite_script\n \xe2\x94\x94\xe2\x94\x807606 sleep 2\n\nMai 28 14:22:21 <host> systemd[1]: Started infinite date service.\n
Run Code Online (Sandbox Code Playgroud)\n\n因此请注意它是如何使用新的 PID 立即重新启动的。
\n\n并检查输出的文件所有权:
\n\nls /tmp/infinite/date\n-rw-r--r-- 1 fiximan fiximan 300 Mai 28 14:31 infinite_date\n
Run Code Online (Sandbox Code Playgroud)\n\n因此该脚本由服务文件中设置的正确用户运行。
\n\n当然,您可以停止并禁用该服务:
\n\nsystemctl stop infinite_script.service\nsystemctl disable infinite_script.service\n
Run Code Online (Sandbox Code Playgroud)\n\n编辑:
\n\n更多细节:用户的个人服务可以(默认情况下)放入$HOME/.config/systemd/user/
并相应管理systemctl --user <commands>
。就像个人 crontab 一样,不需要 root。