本文将介绍如何在 Node.js 中通过 child_process 模块使用 exec、execFile 和 spawn 三种方法来创建子进程运行cmd运行,并通过示例说明了每种方法的参数和输出处理方式。
在介绍子进程前先创建一个node脚本名为printArgs.js,该脚本的作用是接收参数并将参数输出。后续将使用node子进程调用该脚本。脚本代码如下:
// 获取命令行参数,process.argv 是一个数组,其中包含了命令行参数
// 第一个元素是 node 的路径,第二个元素是脚本文件的路径,从第三个元素开始是用户传入的参数
const args = process.argv.slice(2);
// 打印传入的参数
console.log("传入的参数为:");
args.forEach((arg, index) => {
setTimeout(() => {
console.log(`${index + 1}: ${arg}`);
}, (index + 1) * 1000);
});
该脚本通过 process.argv 获取命令行参数,并延迟打印每个参数,模拟异步处理流程。
- process.argv:Node.js 中获取命令行参数的数组:
- argv[0]: Node 可执行文件路径
- argv[1]: 当前执行的脚本路径
- argv[2...]: 用户输入的参数
- setTimeout:每个参数延迟 (index + 1) * 1000 毫秒后打印
创建index.js脚本,引入了 Node.js 的 child_process 模块中的三个方法,下面将分别介绍这三个方法的区别
const { exec, execFile, spawn } = require("child_process");
1.exec
let execChild = exec(
"node ./printArgs.js aaa bbb ccc",
{ encoding: "utf8" },
(error, stdout, stderr) => {
if (error) {
console.log(`执行错误:${error}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
}
console.log(`stdout: ${stdout}`);
}
);
execChild.on("close", (code) => {
console.log(`子进程退出,退出码${code}`);
})
方法说明: exec(command[, options][, callback])
适用场景:执行一条 shell 命令并一次性获取输出(适合小输出量任务),即运行printArgs脚本后将等待3秒一次性输出 aaa bbb ccc
参数:
- command:完整的 shell 命令字符串。
- encoding: 设置输出编码,如 "utf8"。
- callback:回调函数,获取 error、stdout(标准输出)、stderr(错误输出)。
- execChild.on("close", callback):监听子进程关闭事件,获取退出码。
2.execFile
let fileChild = execFile(
"node",
["printArgs.js", "aaa", "bbb", "ccc"],
{ encoding: "utf8", cwd: "" }, //cwd为工作目录
(error, stdout, stderr) => {
if (error) {
console.error(`执行出错: ${error}`);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
}
console.log(`stdout: ${stdout}`);
}
);
fileChild.on("close", (code) => {
console.log(`子进程退出,退出码${code}`);
});
方法说明 execFile(file[, args][, options][, callback])
适用场景:直接运行某个可执行文件,代码中使用node执行printArgs脚本,等待3秒后一次性输出 aaa bbb ccc
参数:
- file: 可执行文件或脚本(如 node)。
- args: 参数数组,即["printArgs.js", "aaa", "bbb", "ccc"]
- cwd: 工作目录(空字符串为当前目录)。
- encoding: 输出编码。
- callback: 同上,获取输出结果。
- fileChild.on("close", callback):监听子进程关闭事件,获取退出码。
3.spawn
const spawnChild = spawn("node", ["./printArgs.js", "aaa", "bbb", "ccc"], {
shell: true,
}); // 在 Windows 上执行 CMD 命令时,通常需要设置 { shell: true }
spawnChild.stdout.on("data", (data) => {
console.log(`stdout: ${data}`);
});
spawnChild.stderr.on("data", (data) => {
console.error(`stderr: ${data}`);
});
spawnChild.on("close", (code) => {
console.log(`子进程退出,退出码 ${code}`);
})
方法说明 spawn(command[, args][, options])
适用场景:持续处理大数据流、监听标准输出/错误(如服务器日志),代码中调用printArgs脚本将每隔1秒输出内容
参数:
- command: 执行命令。
- args: 参数数组,即["./printArgs.js", "aaa", "bbb", "ccc"]
- shell: true:在 Windows 下推荐启用,执行 shell 命令时必要。
- spawnChild.on实时监听标准输出/错误。
总结对比
方法 | 是否用 shell | 适用场景 | 是否支持大数据流 | 回调/事件模型 |
---|---|---|---|---|
exec | 是 | 简单命令 + 小输出 | 否 | 回调函数 |
execFile | 否 | 执行文件 + 安全性要求高 | 否 | 回调函数 |
spawn | 否(可选) | 大数据流 / 持续输出任务 | 是 | 事件监听 |