如何在Express服务接收ajax请求时正确执行child_process.exec命令
问题根因
你遇到的问题本质是不同方式启动的Express进程的运行环境不一致,核心差异有两点:
- 工作目录不匹配:你手动在项目根目录启动进程时,进程的当前工作目录(cwd)就是项目根目录,执行
node script.js可以正常找到目标文件;而通过nodemon后台运行的进程默认工作目录大概率不是项目根目录,执行命令时找不到script.js直接报错,你拿不到nodemon的进程输出所以看不到错误提示。 - 运行用户权限不足:你手动执行命令用的是自己登录服务器的账号,而nodemon如果是作为系统服务/后台任务启动,运行用户可能是低权限的www-data、nobody等账号,没有
script.js的执行权限,也可能没有脚本依赖的配置文件、数据库的访问权限,导致脚本运行失败。
你杀死nodemon手动启动进程时,运行环境和你手动执行脚本的环境完全一致,所以可以正常运行。
修复方案
- 固定脚本路径和执行工作目录
不要用相对路径调用脚本,通过Node.js内置的path模块拼接绝对路径,同时手动指定执行命令的工作目录为项目根目录,参考代码:
const path = require('path') // 调整相对路径保证拼接后是script.js的绝对路径,这里假设CliController在项目的controllers目录下,script.js在根目录 const scriptPath = path.join(__dirname, '../script.js') const projectRoot = path.join(__dirname, '../') cp.exec(`node ${scriptPath} ${ip}`, { cwd: projectRoot }, function (err, stdout, stderr) { if (err) { console.log(err) } console.log(stdout) console.log(stderr) })
- 排查进程权限
执行ps aux | grep nodemon查看nodemon进程的运行用户,给该用户开放script.js的执行权限,以及脚本依赖的所有资源(配置文件、数据库连接权限等)的访问权限。 - 增加日志排查问题
暂时拿不到nodemon输出的情况下,可以把命令的执行日志输出到公共可写目录,方便排查错误:
cp.exec(`node ${scriptPath} ${ip} >> /tmp/script_run.log 2>&1`, {cwd: projectRoot}, callback)
执行完成后查看/tmp/script_run.log即可看到具体的报错信息。
4. 优化命令执行方式(可选)
直接拼接参数存在命令注入的安全风险,建议改用execFile或者spawn的参数传递模式:
cp.execFile('node', [scriptPath, ip], {cwd: projectRoot}, (err, stdout, stderr) => { // 处理逻辑 })
内容的提问来源于stack exchange,提问作者AhmCho
相关产品推荐
相关产品推荐

