Node.js 如何执行命令行二进制程序?

Node.js 执行外部程序用 child_process 模块:exec 执行简单命令拿输出,execFile 直接执行二进制(不经 shell 更安全),spawn 处理流式大输出,execSync 同步执行。本文对比四种方法与适用场景。

最佳实践
Node.js 事件循环与异步任务示意

简单命令用 exec,执行二进制文件用 execFile(不经 shell 更安全),输出量大用 spawn,脚本里图省事用 execSync。

exec:执行 shell 命令

const { exec } = require('child_process');

exec('ls -la /tmp', (error, stdout, stderr) => {
  if (error) {
    console.error(`执行出错: ${error.message}`);
    return;
  }
  console.log(`输出: ${stdout}`);
});

经 shell 执行,能用管道、重定向等 shell 特性;注意输出有 1MB 默认上限(可配 maxBuffer)。

execFile:直接执行二进制(推荐)

const { execFile } = require('child_process');

execFile('/usr/bin/convert', ['input.png', '-resize', '50%', 'output.png'],
  (error, stdout, stderr) => {
    if (error) { console.error(error.message); return; }
    console.log(stdout);
  });

不经 shell,参数以数组传递——天然免疫 shell 注入,参数来自外部输入时必须用它而不是字符串拼接的 exec。

spawn:流式大输出

const { spawn } = require('child_process');

const child = spawn('ffmpeg', ['-i', 'input.mp4', 'output.webm']);

child.stdout.on('data', (data) => console.log(`输出: ${data}`));
child.stderr.on('data', (data) => console.error(`日志: ${data}`));
child.on('close', (code) => console.log(`退出码: ${code}`));

输出按流处理,不装进内存,适合长时间运行、输出量大的命令。

execSync:同步执行

const { execSync } = require('child_process');
const output = execSync('git rev-parse HEAD').toString().trim();

阻塞事件循环,只在 CLI 脚本/构建工具里用。

选型速查

需求 方法
简单命令拿结果 exec
执行二进制+参数来自用户 execFile
大输出/长时运行/要实时日志 spawn
脚本里同步执行 execSync

常见问题(FAQ)

Q:报 Error: spawn XXX ENOENT?
命令不在 PATH 里。用绝对路径,或 spawn 时设 { shell: true }(注意注入风险)。

Q:exec 输出被截断?
默认 maxBuffer 是 1MB。调大 exec(cmd, { maxBuffer: 10*1024*1024 }),或改用 spawn。

Q:Windows 上 .cmd/.bat 执行不了?
Windows 下批处理文件必须经 shell:spawn('npm', { shell: true }) 或用 exec。

参考资料

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台