linux - 如何从另一个启动一个 bash 脚本
问题描述
我试图让一个长期运行的 php cli 进程在 Centos 7 上运行,但收效甚微。所以我使用了几个 bash 脚本 - 一个启动进程,另一个检查进程是否正在运行,如果没有则重新启动它。cron 每两分钟触发一次重启脚本。
这是我的 cron 条目
*/2 * * * * bash /var/www/html/production/start_process.sh
这是我的两个脚本
start_process.sh
#!/bin/bash
if ps -f | grep -q "[p]rocess_queue" ; then echo "Message queue process is already running" ; else bash /var/www/html/production/process_message_queue.sh; fi
process_message_queue.sh
#!/bin/bash
echo "Starting process message queue"
nohup php /var/www/html/production/index.php messages process_queue > process_message_queue.out 2> process_message_queue.err < /dev/null &
echo "Started process message queue"
每个脚本在通过终端运行时都会按预期运行。
bash start_process.sh
要么返回进程正在运行的消息,要么触发第二个脚本,该脚本将正确启动 PHP 进程。
但是,当从 cron 运行时,第一个脚本将启动,并触发第二个脚本。我知道这一点,因为 2 个回显语句出现在 /var/spool/mail/root 中。但是,如果我ps -f
在 cron 作业触发后执行,则该过程不存在。
我有每个 shell 脚本的完整路径,cron 是 root,每个 shell 脚本都归 root 所有。
解决方案
除了修复 PHP 命令的潜在问题(以及它崩溃的原因)之外,我建议将此行为包装为服务而不是 cron 作业。这具有在失败时立即重新启动的额外好处(与 cron 不同,您必须等到下一分钟)。例如,如果您使用的是 systemd,则可以添加以下服务 ( /etc/systemd/system/charliefortune.service
):
[Unit]
Description=CharlieFortuneService
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/var/www/html/production/process_message_queue.sh
[Install]
WantedBy=multi-user.target
并更改process_message_queue.sh
为:
#!/bin/bash
echo "Starting process message queue"
php /var/www/html/production/index.php messages process_queue > process_message_queue.out 2> process_message_queue.err # This blocks
echo "Started process message queue"
您还将在服务管理器中获得一些不错的日志记录输出
我意识到这更像是评论而不是答案,但我缺乏对您的问题发表评论的声誉。
推荐阅读
- java - 使用java列出和映射csv文件的数据
- html - how can i fix my web page navigetion bar?
- python - 我想使用pickle存储一个具有另一个对象列表的对象
- typescript - 找出班级中五个科目的百分比
- json - 如何将字符串列表或字符串列表传递给 terragrunt / terraform 中的数据模板
- javascript - 在反应传单中使用带有大量数据的 Geojson
- javascript - Sequelize:使用关联创建不起作用
- git - 特定文件不断从 git 中删除
- python - 升级到 postgrers12 后返回的 django 记录的顺序发生了变化?
- java - 我在收集过程中得到错误的输出