Node.js中使用spawn调用Python脚本,API触发无响应问题
Node.js调用Python交易脚本无预期效果的排查与修复
我通过Node.js实现了marketOrder接口,计划用child_process.spawn调用Python脚本执行交易操作,但调用该API后没有产生预期效果,虽然Node.js服务本身运行正常。
原代码
exports.marketOrder = async (req, res) => { console.log("fgfdgf"); const { spawn } = require("child_process"); let action = "buy", symbol = "XAUUSD", lot = 0.1, sl_points = 100, tp_points = 100, deviation = 20; const process = spawn("python", [ "-c", ``import metapython; print(metapython.open_trade("${action}", "${symbol}", ${lot}, ${sl_points}, ${tp_points}, ${deviation}) `````)`, ]); let order = null; process.stdout.on("data", (data) => { const frg = data.toString(); const regex = /order=(\d+)/; const orderMatch = frg.match(regex); order = orderMatch ? parseInt(orderMatch[1]) : null; }); }; router.post("/marketOrder", marketOrder);
问题分析
- 模板字符串语法错误:Python命令的模板字符串用了嵌套反引号,导致语法解析失败,Python无法正确执行命令。
- 未监听错误输出:只监听了子进程的
stdout,没有处理stderr,Python脚本执行出错时无法获取错误信息,难以排查问题。 - 未返回响应给客户端:接口函数未调用
res.send/res.json,客户端会一直处于等待状态,也无法得知执行结果。 - 未等待子进程执行完成:接口是异步函数,但没有等待子进程结束就可能结束,导致订单ID还未获取到。
修复后的代码
exports.marketOrder = async (req, res) => { console.log("触发marketOrder接口"); const { spawn } = require("child_process"); let action = "buy", symbol = "XAUUSD", lot = 0.1, sl_points = 100, tp_points = 100, deviation = 20; // 修复模板字符串,用单引号包裹Python命令避免嵌套冲突 const pythonCmd = `import metapython; print(metapython.open_trade("${action}", "${symbol}", ${lot}, ${sl_points}, ${tp_points}, ${deviation}))`; const process = spawn("python", ["-c", pythonCmd]); let order = null; let errorMsg = ""; // 处理标准输出,提取订单ID process.stdout.on("data", (data) => { const output = data.toString().trim(); const regex = /order=(\d+)/; const orderMatch = output.match(regex); order = orderMatch ? parseInt(orderMatch[1]) : null; }); // 收集错误信息,用于排查问题 process.stderr.on("data", (data) => { errorMsg += data.toString(); }); // 子进程结束后统一返回响应 process.on("close", (code) => { if (code !== 0) { return res.status(500).json({ success: false, message: "Python脚本执行失败", error: errorMsg }); } if (!order) { return res.status(400).json({ success: false, message: "未获取到有效订单ID", output: errorMsg }); } res.json({ success: true, orderId: order }); }); }; router.post("/marketOrder", marketOrder);
额外排查步骤
- 单独测试Python命令:在终端执行
python -c "import metapython; print(metapython.open_trade('buy', 'XAUUSD', 0.1, 100, 100, 20))",确认脚本本身能正常运行并输出订单ID。 - 检查Python环境:确保Node.js调用的
python版本正确,且已安装metapython模块,环境与手动执行时一致。 - 查看Node.js日志:确认
console.log内容是否打印,验证接口确实被触发。
内容的提问来源于stack exchange,提问作者Ajmal
相关产品推荐
相关产品推荐

