【问题标题】:How to start one bash script from another如何从另一个启动一个 bash 脚本
【发布时间】:2020-02-21 10:22:22
【问题描述】:

我试图让一个长期运行的 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 中。 但如果我在 cron 作业触发后执行 ps -f,则该进程不存在。

我有每个 shell 脚本的完整路径,cron 是 root,每个 shell 脚本都归 root 所有。

【问题讨论】:

  • 您是否希望在进程中看到 shell 脚本?一旦执行了命令,它将关闭脚本/shell,除非它是一个实时进程)。
  • 我期待看到 php 脚本 - 这是一个永久循环,我没有将其发送到后台。
  • process_message_queue.out/err 文件中有任何内容吗?一个简单的解释是,由 php 生成的进程几乎会因为错误而立即退出,例如,如果它依赖于未在 cronjob 上下文中设置的环境变量,则可能会发生这种情况
  • 不,它们是空的,这也令人费解。由于缺少全局变量,我以前确实遇到过 env 错误,但解决了这些问题,正如(我相信)我可以通过终端执行两个 shell 脚本,并且进程保持在后台运行这一事实所证明的那样。
  • 可以不放一些调试语句吗?例如echo date > /tmp/start.txt 等,看看它实际到达了哪里?从你的 shell 运行它并不一定意味着它与 cron 相同 - 例如,如果从 Cron 运行,你可能需要 cd 到目录/使用完整路径(而你的 shell 将保留它们)。你说你确定它正在运行,但我认为情况可能并非如此。也许在 php 调用之前和之后放置一些步骤,并且不要通过 nohup 运行 - 例如,为什么不只是将进程置于后台?还是将进程日志重定向到另一个文件进行调试?

标签: linux bash shell cron command-line-interface


【解决方案1】:

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

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

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

【讨论】:

  • 这很好,谢谢。我意识到我的方法有缺陷,我是出于绝望而得到这个解决方案来解决问题的,真的。
猜你喜欢
  • 2019-07-10
  • 2022-08-22
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 2019-06-22
  • 2023-01-13
  • 1970-01-01
  • 2015-08-25
相关资源
最近更新 更多