NodeJs内置模块child_process

内置模块child_process子进程

写在前面

子进程是Nodejs的核心Api,如果你会shell命令,它会有非常大的帮助,或者你喜欢编写前端工程化工具之类,它也有很大的用处,以及处理CPU密集型应用。

创建子进程

Nodejs创建子进程共有7个API,带Sync的是同步API,不加的是异步API:

  1. spwan:执行命令
  2. exec:执行命令
  3. execFile:执行可执行文件
  4. fork:创建node子命令
  5. execSync:执行命令 同步执行
  6. execFileSync:执行可执行文件 同步执行
  7. spawnSync:执行命令 同步执行

1. exec()和execSync()

exec()异步的方法 可以帮我们执行shell命令 或者跟软件交互 回调函数返回一个buffer。

我们首先介绍exec()execSync()命令的第一个用途:执行shell命令

我们尝试使用exec()执行shell命令输出node版本

const { exec } = require("child_process");
exec("node -v", (err, stdout, stderr) => {
  if (err) {
    console.log(err);
    return;
  }
  // 返回的是buffer 转成字符后输出
  console.log("exec", stdout.toString()); // v16.17.0
});

execSync() 同步的方法 一般同步的用的比较多 异步写法太麻烦了。

这两种方法都比较适合执行较小的shell命令 想要立马拿到结果的shell命令

但是这两种方法有个缺点:返回的字节上限200kb 超出就会报错

使用execSync()执行shell命令输出node版本

const { execSync } = require("child_process");
const nodeVersion = execSync("node -v");
console.log("execSync", nodeVersion.toString()); // v16.17.0

使用execSync()创建文件夹test:因为mkdir命令没有返回值,因此不用接收结果

execSync("mkdir test");  // 可以看到当前目录中多了一个test文件夹

下面我们再介绍exec()execSync()命令的第二个用途:跟软件交互

这里就以execSync()为例,尝试打开chrome的百度页面:

execSync("start chrome http://www.baidu.com");

运行此代码可以成功百度页,下面我们再试试使用execSync()启动电脑上的steam,我们需拿到steam运行程序的路径:

execSync("D:\\Steam\\Steam.exe");

运行代码后等待一会【启动应用程序需要时间】可以看到steam成功启动,需要注意的是:commonjs规范下路径需要双反斜杠进行转码。

2. spawn()和spawnSync()

spawn()spawnSync()也是用来执行shell命令,并且返回的字节大小没有上限 因为返回的是个流 并且是实时返回的,而exec()execSync()需要等待shell命令运行结束,拿到所有的返回结果的才算结束。

spawnSync()用的比较少。

这里我们扩展一下netStat的相关知识:

shell命令netStat是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。

NodeJs内置模块child_process_第1张图片

下面我们先使用execSync()执行shell命令netStat获取本机网络状态。

const { execSync } = require("child_process");
const netstat = execSync("netstat");
console.log(netstat.toString());  // 需要等待运行完才输出

NodeJs内置模块child_process_第2张图片

可以看到网络状态并不会实时的一条一条的输出,下面我们使用spawn()执行shell命令netStat获取本机网络状态。

spwan()的用法和exec()差异不小,它需要从返回结果中解构出stdout,并使用on监听返回的数据,并且每一条数据都是buffer类型,需要转字符输出才能看得懂,另外,spwan()不仅能实时输出运行结果,使用on还能监听命令运行结束,这是exec所不具有的。

const { spawn } = require("child_process");
const { stdout } = spawn("netstat");
stdout.on("data", (data) => {
  console.log(data.toString());
});
stdout.on("close", () => {
  console.log("结束了");
});

NodeJs内置模块child_process_第3张图片

可以看到控制台实时输出了每一个网络的当前状态。

增加shell命令参数的格式和exec()不同,exec()是直接在shell命令后面增加,就和在命令行输入一样,spawn()增加shell命令参数的格式如下:

const { spawn } = require("child_process");
const { stdout } = spawn("netstat", ["-a"]);  // 增加shell命令参数
stdout.on("data", (data) => {
  console.log(data.toString());
});
stdout.on("close", () => {
  console.log("结束了");
});

3. 未完待补充

参考博客:

  1. https://xiaoman.blog.csdn.net/article/details/132797154?spm=1001.2014.3001.5502
  2. https://blog.csdn.net/weixin_44299027/article/details/123741176

你可能感兴趣的:(Node.js,项目工程化,前端,node.js,child_process,后端,开发语言,process)