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

Apache下PHP调用shell_exec执行Shell脚本重启Java进程失效排查

问题原因排查与修复方案

核心故障原因

  • 权限不足:PHP作为Apache的子进程运行,默认使用低权限业务用户(常见为apache、www-data),没有启停系统服务、强杀其他用户进程的权限。手动在终端执行脚本时用的是登录账号(一般是root或有sudo权限的运维账号),所以能正常运行,PHP触发时所有需要高权限的操作都会被系统拦截。
  • 相对路径失效:脚本里启动jar包用的是相对路径RSN_API_Controller.jar,PHP执行shell命令时的工作目录不是脚本所在的/opt/APIController/,会直接报找不到jar文件,启动失败。
  • 环境变量缺失:PHP触发shell执行时不会加载用户全局/个人的环境变量配置,经常出现找不到java、service等命令的情况,导致命令执行中断。
  • 输出流阻塞:nohup启动进程时没有重定向标准输出和错误输出,shell_exec函数会等待所有输出流关闭才会结束执行,容易导致进程挂死、启动异常。

分步修复操作

第一步:修正Shell脚本内容

替换原有脚本为以下版本,补全绝对路径、环境变量加载、输出重定向逻辑:

#!/bin/bash
# 加载系统环境变量
source /etc/profile
[ -f ~/.bashrc ] && source ~/.bashrc
# 强制切换到脚本所在工作目录
WORK_DIR=/opt/APIController
cd $WORK_DIR

# 注意:如果不知道命令的绝对路径,可以在服务器执行which service、which java查询对应路径
/usr/sbin/service cassandra start
/usr/sbin/service httpd start

prid=$(ps aux| egrep '[R]SN_API_Controller.jar' | awk '{print $2}')
if [ -z "$prid" ]
then
        echo "No process to kill"
else
        kill -9 $prid
        echo "Successfully service stopped"
fi

pridold=$(ps aux| egrep '[R]snBlacklist.jar' | awk '{print $2}')
if [ -z "$pridold" ]
then
        echo "No process to kill"
else
        kill -9 $pridold
        echo "Successfully service stopped old jar file"
fi

# 重定向所有输出到日志文件,避免流阻塞
nohup /usr/bin/java -Djsse.enableSNIExtension=false -jar RSN_API_Controller.jar > $WORK_DIR/api_controller.log 2>&1 &

echo "Successfully service started"

修改完成后给脚本加可执行权限:
chmod +x /opt/APIController/RSN_API_Controller_start.sh

第二步:配置最小化sudo权限

不要给PHP运行用户全量root权限,仅开放该脚本的执行权限即可:

  1. 执行visudo命令打开sudo配置文件
  2. 先找到Defaults requiretty配置行,前面加#注释掉,否则sudo执行会报无tty终端的错误
  3. 在文件末尾新增一行(如果你的Apache运行用户是www-data,就把下面的apache替换成实际用户,可通过ps aux | grep httpd查看第一列的运行用户确认):
    apache ALL=(ALL) NOPASSWD: /opt/APIController/RSN_API_Controller_start.sh
    
  4. 保存退出配置文件

第三步:调整PHP调用代码

修改原有调用逻辑,加sudo执行,同时保留输出方便调试:

<?php
     //some lines
     // 2>&1 会把错误输出也合并到返回结果里,方便定位问题
     $exec_result = shell_exec('sudo /bin/bash /opt/APIController/RSN_API_Controller_start.sh 2>&1');
     // 调试阶段可以打印结果看具体报错,功能正常后可注释
     var_dump($exec_result);
     //some lines
?>

快速排查技巧

如果配置后仍无法正常执行,可以先写一个测试PHP文件,内容为<?php echo shell_exec('whoami');,访问该文件确认PHP实际运行用户,再对应调整sudo配置即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 17:18:20