You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何执行在Apache重启后仍能继续运行的bash脚本

解决方案

核心思路是让bash脚本完全脱离Apache的进程会话、进程组,不受Apache生命周期影响,以下是经过验证的可行方案:

方案1:使用nohup+后台运行(最简便)

你之前的screen方案无效大概率是没有完成完整的会话脱离操作,nohup的实现方式更简单直接,PHP调用写法如下:

shell_exec('nohup /path/to/your/target.sh > /var/log/script_run.log 2>&1 & echo $!');

关键配置说明:

  • nohup会让进程忽略SIGHUP信号,避免父进程退出时被连带杀死
  • 所有输入输出重定向到日志文件(也可以写/dev/null丢弃输出),避免进程因为IO未处理被挂起
  • 末尾的&让进程直接后台运行,不会阻塞PHP执行
  • 可选添加echo $!返回后台进程PID,方便后续排查问题

方案2:使用systemd临时服务(生产环境更稳定)

如果脚本逻辑复杂、运行时间长,推荐用systemd托管运行,完全和Apache进程解绑:

  1. 先写通用服务单元模板,保存到/etc/systemd/system/run-custom-script@.service:
[Unit]
Description=Run custom user script %I

[Service]
Type=oneshot
ExecStart=/bin/bash /path/to/your/scripts/%I
User=root # 按需替换为脚本运行需要的用户
Group=root
  1. 重载systemd配置后在PHP中调用触发即可:
shell_exec('systemctl start run-custom-script@your_script_name.sh --no-block');

优势:

  • 完全脱离Apache进程树,Apache重启/停止完全不会影响脚本运行
  • 自动记录运行日志,可通过journalctl -u run-custom-script@your_script_name.sh查看执行记录
  • 支持配置失败重试、运行超时等扩展规则

方案3:使用at命令调度立即执行

如果系统运行了atd服务,也可以直接把脚本丢给at调度立即执行,自动脱离父进程:

shell_exec('echo "/path/to/your/target.sh" | at now');

注意事项:

  • 需要提前安装at包并确保atd服务处于运行状态
  • 适合对启动延迟要求不高的场景

原screen方案修复方式

如果还是需要用screen,要在启动参数中加-d -m强制启动为分离模式,不要附着在当前会话上,写法参考:

shell_exec('screen -d -m -S script_task /path/to/your/target.sh');

之前调用screen无效基本都是没有加-d -m参数,导致screen进程依然和Apache的会话绑定,Apache停止时会被一起杀死。

内容的提问来源于stack exchange,提问作者TurboDaaaan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 16:18:01