Node.js的child_process.exec默认超时是60秒,而非无限;其内部timeout设为0会触发60秒后强制终止子进程的fallback机制。
Node.js 的 child_process.exec 默认超时是 0?不,是 60 秒
很多人以为 exec 不设 timeout 就是“永不超时”,其实不然。Node.js 内部默认把 timeout 设为 0,但这个 0 并非“不限制”,而是触发一个 fallback 行为:当子进程卡住、stdout/stderr 无输出且未退出时,Node 会在 60 秒后强制 kill 掉它,并抛出 Error: Command failed: timeout 或类似 spawn ETIMEDOUT 的错误。
如果你的 PHP 脚本要跑 90 秒(比如导出大数据报表、处理图像队列),不显式设置 timeout,大概率在第 61 秒被砍断。
实操建议:
- 始终显式传入
timeout选项,哪怕设为300000(5 分钟) - 注意单位是毫秒,不是秒 ——
{ timeout: 120000 }是 2 分钟 - 配合
killSignal: 'SIGTERM'更友好,避免 PHP 进程残留
execFile 比 exec 更稳,尤其调用 PHP CLI
exec 会经过 shell 解析(如 /bin/sh -c),容易因空格、特殊字符或环境变量导致意外截断或注入;而 execFile 直接执行二进制,更可控、启动更快、也更少受 shell 超时策略干扰。
立即学习“PHP免费学习笔记(深入)”;
调用 PHP 脚本的典型写法:
const { execFile } = require('child_process');
execFile('php', ['script.php', '--arg=value'], {
timeout: 180000,
maxBuffer: 10 * 1024 * 1024 // 防止大输出撑爆内存
}, (err, stdout, stderr) => {
if (err && err.code === 'ETIMEOUT') {
console.error('PHP 脚本执行超时');
}
});
关键点: