Node.js child_process模块
child_process 模块用于创建和管理子进程。
四种方法对比
| 方法 | 特点 | 适用场景 |
|---|---|---|
exec | 缓存输出,shell执行 | 简单命令 |
execFile | 缓存输出,直接执行文件 | 可执行文件 |
spawn | 流式输出,返回流 | 大数据流 |
fork | 专为Node.js脚本,内置IPC | Node子进程 |
exec 方法
基本用法
JavaScript
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('输出:', stdout);
});
带选项
JavaScript
exec('ls -la', {
cwd: '/home/user', // 工作目录
env: { PATH: '/usr/bin' }, // 环境变量
encoding: 'utf8', // 编码
timeout: 5000, // 超时时间(ms)
maxBuffer: 200 * 1024, // 最大缓冲区
shell: '/bin/bash' // shell路径
}, (error, stdout, stderr) => {
console.log(stdout);
});
execFile 方法
基本用法
JavaScript
const { execFile } = require('child_process');
execFile('node', ['--version'], (error, stdout, stderr) => {
console.log('Node版本:', stdout);
});
// 执行脚本
execFile('./script.sh', (error, stdout, stderr) => {
console.log(stdout);
});
spawn 方法
基本用法
JavaScript
const { spawn } = require('child_process');
const child = spawn('ls', ['-la', '/home']);
// 流式读取输出
child.stdout.on('data', (data) => {
console.log('输出:', data.toString());
});
child.stderr.on('data', (data) => {
console.error('错误:', data.toString());
});
child.on('close', (code) => {
console.log('退出码:', code);
});
管道操作
JavaScript
const { spawn } = require('child_process');
// grep 搜索
const grep = spawn('grep', ['node']);
const ls = spawn('ls', ['-la']);
// 管道连接
ls.stdout.pipe(grep.stdin);
grep.stdout.on('data', (data) => {
console.log('匹配:', data.toString());
});
交互式输入
JavaScript
const child = spawn('node', ['-i']);
// 向子进程写入
process.stdin.pipe(child.stdin);
child.stdout.pipe(process.stdout);
fork 方法
基本用法
JavaScript
const { fork } = require('child_process');
// fork 只能执行 Node.js 模块
const child = fork('./worker.js', ['arg1', 'arg2']);
// IPC 通信
child.on('message', (msg) => {
console.log('收到消息:', msg);
});
child.send({ type: 'task', data: 'hello' });
child.on('exit', (code) => {
console.log('子进程退出:', code);
});
Worker 示例
JavaScript
// main.js
const { fork } = require('child_process');
const workers = [];
for (let i = 0; i < 4; i++) {
const worker = fork('./worker.js');
workers.push(worker);
worker.on('message', (result) => {
console.log(`Worker ${i} 结果:`, result);
});
}
// 分发任务
workers.forEach((worker, i) => {
worker.send({ taskId: i, data: 'task' });
});
// worker.js
process.on('message', (msg) => {
// 处理任务
const result = processData(msg.data);
process.send({ taskId: msg.taskId, result });
});
function processData(data) {
return 'processed: ' + data;
}
同步方法
JavaScript
const { execSync, execFileSync, spawnSync } = require('child_process');
// execSync
const output = execSync('ls -la', { encoding: 'utf8' });
console.log(output);
// execFileSync
const version = execFileSync('node', ['--version'], { encoding: 'utf8' });
console.log(version);
ChildProcess 对象
属性
JavaScript
const child = spawn('ls');
console.log(child.pid); // 进程ID
console.log(child.stdin); // 标准输入流
console.log(child.stdout); // 标准输出流
console.log(child.stderr); // 标准错误流
console.log(child.stdio); // [stdin, stdout, stderr]
方法
JavaScript
child.send(msg); // 发送消息(fork)
child.disconnect(); // 断开IPC连接
child.kill(); // 终止进程
child.kill('SIGTERM'); // 发送信号
child.ref(); // 保持父进程运行
child.unref(); // 允许父进程独立退出
注意事项
exec缓存输出,不适合大数据spawn流式输出,适合大数据流fork只能执行 Node.js 模块- 子进程默认继承父进程环境变量
- 同步方法会阻塞主线程
要点总结
exec执行 shell 命令,缓存输出spawn启动进程,流式处理输出fork专为 Node.js 子进程,内置 IPCchild.send()和process.on('message')进程通信- 同步方法阻塞,谨慎使用
📝 发现内容有误?点击此处直接编辑