首页 > 解决方案 > 如何从另一个启动一个 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 所有。

标签: linuxbashshellcroncommand-line-interface

解决方案


除了修复 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"

您还将在服务管理器中获得一些不错的日志记录输出

我意识到这更像是评论而不是答案,但我缺乏对您的问题发表评论的声誉。


推荐阅读