当前位置: 首页 > news >正文

exec和spawn

前言

需求:做一个electron应用,用node打开exe软件,打开后返回成功与否,打开的软件不会随electron应用的关闭而关闭

exec

exec 第一个参数为要运行的command命令,参数以空格分隔。

child_process.exec(command[, options][, callback])

exec会衍生 shell,然后在该 shell 中执行 command,缓冲任何生成的输出。传递给 exec 函数的 command 字符串由 shell 直接处理,特殊字符(根据 shell 有所不同)需要进行相应处理。
例如,如果exe文件的名称中有空格,那么需要用引号包裹之后才能调用

child_process.exec(`"${appName}"`)

exec的callback 函数的参数是:error, stdout, stderr。成功后,error 将是 null,出错时,error 将是 Error 的实例。error.code 属性将是进程的退出码。按照惯例,除 0 之外的任何退出码都表示错误。error.signal 将是终止进程的信号。

传给回调的 stdoutstderr 参数将包含子进程的标准输出和标准错误的输出。默认情况下,Node.js 会将输出解码为 UTF-8 并将字符串传给回调。

const { exec } = require('node:child_process');
exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {if (error) {console.error(`exec error: ${error}`);return;}console.log(`stdout: ${stdout}`);console.error(`stderr: ${stderr}`);
});

如果把exec用util.promisify() 包裹,就会返回一个Promisestdoutstderr 是它返回的属性。如果出现错误(包括任何导致退出码不是 0 的错误),则将返回被拒绝的 Promise,其具有与回调中给定相同的 error 对象,但有两个额外的属性 stdoutstderr

const util = require('node:util');
const exec = util.promisify(require('node:child_process').exec);try {const { stdout, stderr } = await exec('ls')console.log('stdout:', stdout);console.error('stderr:', stderr);
} catch (e) {console.error('Error:', ${(e as Error).message});
}

exec其实是封装了spawn。

spawn

异步衍生子进程,不会阻塞 Node.js 事件循环。在父 Node.js 进程和衍生的子进程之间建立 stdin、stdout 和 stderr 的管道,第一个参数为要运行command命令,参数使用字符串数组(string[])的形式传入第二个参数当中。

child_process.spawn(command[, args][, options])

options中,使用 cwd 指定从中衍生进程的工作目录。如果没有给定,则默认是继承当前工作目录。如果给定,但路径不存在,则子进程会触发 ENOENT 错误并立即退出。当命令不存在时,也会触发 ENOENT。使用 env 指定对新进程可见的环境变量,默认为 process.env

const { spawn } = require('node:child_process');
const ls = spawn('ls', ['-lh', '/usr']);ls.stdout.on('data', (data) => {console.log(`stdout: ${data}`);
});ls.stderr.on('data', (data) => {console.error(`stderr: ${data}`);
});ls.on('close', (code) => {console.log(`child process exited with code ${code}`);
});

如果想使用promise的方式调用spawn,则需要借助一些库才能实现。

调用exe

传入要调用exe的绝对路径appPath

import { spawn } from 'child_process';
import * as path from 'path';const normalizedPath = path.normalize(appPath);
const appDir = path.dirname(normalizedPath);
const appName = path.basename(normalizedPath);
const child = spawn(`"${appName}"`, [], { shell: true, cwd: appDir, env });

相关文章:

  • 软件工程效率优化:一个分层解耦与熵减驱动的系统框架
  • 系统思考:看清问题背后的结构
  • 无人售货机系统对接全流程拆解,4 步教你搭建私有化系统
  • Canvas入门教程!!【Canvas篇二】
  • JDBC之ORM思想及SQL注入
  • Java知识日常巩固(四)
  • 30天通过软考高项-第三天
  • 代码随想录算法训练营第60期第十七天打卡
  • 推荐一些实用的慢SQL优化方案
  • 使用kubeadmin 部署k8s集群
  • Vue3 自定义指令完全指南
  • Unity中数据和资源加密(异或加密,AES加密,MD5加密)
  • Python爬虫(5)静态页面抓取实战:requests库请求头配置与反反爬策略详解
  • Git 入门知识详解
  • 后知后觉!要是大学就有这些 AI 工具,我能多拿多少奖学金
  • k8s(9) — zookeeper集群部署(亲和性、污点与容忍测试)
  • ESG跨境电商如何为国内的跨境电商企业打开国外的市场
  • 探秘 roadmap.sh:GitHub 最受欢迎的开发者学习路线图项目
  • 组件化开发
  • 「零配置陷阱」:现代全栈工具链的复杂度管控实践
  • 铁线礁、牛轭礁珊瑚礁“体检”报告首次发布,专家:菲非法活动产生胁迫性影响
  • 美称中美芬太尼问题谈判但中方不够真诚,外交部回应
  • 解放日报头版:外资汽车产业链布局上海步伐明显加快
  • 限时离境、关闭领空、暂停贸易,巴基斯坦宣布一系列对印反制措施
  • 下周起上海浦东将投放5000万元消费券,预计分五周发放
  • 云南洱源县4.8级地震:房屋受损442户,无人员伤亡报告