child_process 子进程
子进程是Nodejs核心API,如果你会shell命令,他会有非常大的帮助,或者你喜欢编写前端工程化工具之类的,他也有很大的用处,以及处理CPU密集型应用。
1const { exec, execSync, spawm, spawnSync, execFile, execFileSync, fork } = require("node:child_process");
创建子进程
Nodejs创建子进程共有 7
个API(Sync同步API,不加是异步API)
API |
含义 |
exec |
执行命令 |
execSync |
执行命令,同步执行 |
execFile |
执行可执行文件 |
execFileSync |
执行可执行文件,同步执行 |
spawn |
执行命令 |
spawnSync |
执行命令,同步执行 |
fork |
创建node子进程 |
exec
执行命令
1# 语法
2child_process.exec(command, [options], callback);
-
command
-
options
- cwd <string> 子进程的当前工作目录。
- env <Object> 环境变量键值对。
- encoding <string> 默认为 'utf8'。
- shell <string> 用于执行命令的 shell。 在 UNIX 上默认为 '/bin/sh',在 Windows 上默认为 process.env.ComSpec。 详见 Shell Requirements 与 Default Windows Shell。
- timeout <number> 默认为 0。
- maxBuffer <number> stdout 或 stderr 允许的最大字节数。 默认为 200*1024。 如果超过限制,则子进程会被终止。 查看警告: maxBuffer and Unicode。
- killSignal <string> | <integer> 默认为 'SIGTERM'。
- uid <number> 设置该进程的用户标识。(详见 setuid(2))
- gid <number> 设置该进程的组标识。(详见 setgid(2))
-
callback
示例
1// 获取 nodejs 版本号
2exec("node -v", (err, stdout, stderr) => {
3 if (err) {
4 return err;
5 }
6 console.log(stdout.toString());
7});
execSync
1// 获取node版本号 如果要执行单次 shell 命令execSync方便一些
2const nodeVersion = execSync("node -v");
3console.log(nodeVersion.toString("utf-8"));
1// 打开谷歌浏览器:使用 exec 可以打开一些软件,例如wx、谷歌、qq音乐等,以下会打开百度并且进入无痕模式
2try {
3 // macos
4 execSync(
5 'open -a "Google Chrome" --args --incognito "https://www.baidu.com"'
6 );
7 // windows
8 execSync('start chrome --incognito "https://www.baidu.com"');
9 // linux
10 execSync('google-chrome --incognito "https://www.baidu.com"');
11} catch (error) {
12 console.error("Failed to open Chrome", error);
13}
execFile
execFile 适合执行可执行文件,例如执行一个node脚本,或者shell文件,windows可以编写cmd脚本,posix,可以编写sh脚本
简单示例
创建一个文件夹mkdir 进入目录 写入一个文件test.js 最后执行
使用execFile 执行这个
1execFile(path.resolve(process.cwd(), "./bat.cmd"), null, (err, stdout) => {
2 console.log(stdout.toString());
3});
spawn
spawn 用于执行一些实时获取的信息因为spawn返回的是流边执行边返回,exec是返回一个完整的buffer,buffer的大小是200k,如果超出会报错,而spawn是无上限的。
spawn在执行完成后会抛出close事件监听,并返回状态码,通过状态码可以知道子进程是否顺利执行。exec只能通过返回的buffer去识别完成状态,识别起来较为麻烦
1const { stdout } = spawn("netstat", ["-an"], {});
2
3//返回的数据用data事件接受
4stdout.on("data", (steram) => {
5 console.log(steram.toString());
6});
7stdout.on("close", (steram) => {
8 console.log("结束了");
9});
exec -> execFile -> spawn
exec是底层通过execFile实现 execFile底层通过spawn实现
fork
场景适合大量的计算,或者容易阻塞主进程操作的一些代码,就适合开发fork
1const testProcess = fork("./test.js");
2
3// 发送消息
4testProcess.send("我是主进程");
5
6// 接收消息
7testProcess.on("message", (data) => {
8 console.log("我是主进程接受消息111:", data);
9});
1// 接收消息
2process.on("message", (data) => {
3 console.log("子进程接受消息:", data);
4});
5
6// 发送消息
7process.send("我是子进程");
:::
send 发送信息 ,message接收消息,可以相互发送接收。
fork底层使用的是IPC通道进行通讯的,
