Node.js的Child Process模块允许主进程创建子进程来执行外部命令或脚本,实现与操作系统层面的交互,是扩展Node.js能力的重要工具。该模块内置在Node.js标准库中,无需额外安装即可直接使用。

Child Process模块的核心方法
Child Process模块提供了多个创建子进程的API,不同方法适用于不同的使用场景,下面介绍最常用的几种。
1. exec方法
exec方法适合执行输出内容较少的外部命令,它会将命令的输出缓存起来,执行完成后通过回调函数返回结果。该方法会自动调用系统的shell来执行命令,支持shell语法比如管道、重定向等。
const { exec } = require('child_process');
// 执行查看当前目录文件的命令
exec('ls -la', (error, stdout, stderr) => {
if (error) {
console.error(`执行出错: ${error.message}`);
return;
}
if (stderr) {
console.error(`错误输出: ${stderr}`);
return;
}
// 打印命令的标准输出
console.log(`命令输出:n${stdout}`);
});
exec方法有一个可选的options参数,可以配置执行超时时间、工作目录、环境变量等,比如设置超时时间避免命令长时间运行:
const { exec } = require('child_process');
exec('sleep 5', { timeout: 3000 }, (error, stdout, stderr) => {
if (error) {
// 超过3秒会触发超时错误
console.error(`执行出错: ${error.message}`);
return;
}
});
2. spawn方法
spawn方法适合执行输出大量数据的命令,它不会缓存输出,而是通过流的方式返回数据,避免占用过多内存。spawn方法默认不会调用shell,需要直接传入命令和参数数组。
const { spawn } = require('child_process');
// 执行ping命令,持续输出结果
const pingProcess = spawn('ping', ['www.ipipp.com', '-c', '4']);
// 监听标准输出流
pingProcess.stdout.on('data', (data) => {
console.log(`输出: ${data}`);
});
// 监听错误输出流
pingProcess.stderr.on('data', (data) => {
console.error(`错误: ${data}`);
});
// 监听进程退出事件
pingProcess.on('close', (code) => {
console.log(`子进程退出,退出码: ${code}`);
});
3. execFile方法
execFile方法直接执行可执行文件,不会调用shell,比exec方法更安全,适合执行已知路径的脚本或程序,避免shell注入风险。
const { execFile } = require('child_process');
// 执行当前目录下的test.sh脚本
execFile('./test.sh', ['参数1', '参数2'], (error, stdout, stderr) => {
if (error) {
console.error(`执行出错: ${error.message}`);
return;
}
console.log(`脚本输出: ${stdout}`);
});
4. fork方法
fork方法是spawn方法的特殊形式,专门用于创建新的Node.js进程,执行Node.js脚本,父子进程之间可以通过内置的通信通道传递消息。
// 主进程代码 main.js
const { fork } = require('child_process');
const child = fork('./child.js');
// 向子进程发送消息
child.send({ type: 'start', data: 'hello' });
// 接收子进程返回的消息
child.on('message', (msg) => {
console.log(`收到子进程消息: ${msg}`);
});
// 子进程代码 child.js
process.on('message', (msg) => {
console.log(`子进程收到消息: ${JSON.stringify(msg)}`);
// 向主进程返回处理结果
process.send('处理完成');
});
同步执行外部命令的方法
如果需要在执行外部命令完成后再继续后续逻辑,并且不希望使用回调或者Promise,可以使用同步版本的方法,这些方法会阻塞主进程直到命令执行完成。
const { execSync, spawnSync } = require('child_process');
// 同步执行命令,返回输出结果
try {
const output = execSync('ls -la');
console.log(`同步执行结果:n${output}`);
} catch (error) {
console.error(`执行失败: ${error.message}`);
}
// spawnSync的使用方式
const result = spawnSync('echo', ['hello world']);
console.log(`输出: ${result.stdout.toString()}`);
需要注意同步方法会阻塞Node.js主进程,如果在主线程中使用,会导致后续请求无法处理,因此只建议在脚本工具类场景使用,不建议在Web服务中使用。
常见问题与注意事项
- 执行命令时如果需要传递包含空格的参数,spawn方法需要把参数拆分到数组中,不要直接拼接成字符串,否则会被当成单个参数。
- 使用exec方法执行输出量大的命令时,可能会因为输出缓存区满导致进程卡住,这种场景应该优先使用spawn方法。
- 执行外部命令时要注意权限问题,比如执行系统命令需要对应的用户权限,执行脚本需要脚本有可执行权限。
- 子进程执行完成后要及时处理,避免僵尸进程占用系统资源,可以通过监听close或者exit事件来处理后续逻辑。
方法选择参考
可以通过下面的场景判断选择哪种方法:
| 使用场景 | 推荐方法 |
|---|---|
| 执行简单命令,输出内容少,需要shell语法支持 | exec |
| 执行命令输出大量数据,需要流式处理 | spawn |
| 执行已知的可执行文件,避免shell注入 | execFile |
| 执行Node.js脚本,需要父子进程通信 | fork |
| 脚本工具场景,需要同步等待命令执行完成 | execSync/spawnSync |
Node.jsChild_Process执行外部命令子进程spawn修改时间:2026-07-15 19:15:36