
开发工具【免费下载链接】execaProcess execution for humans项目地址https://gitcode.com/gh_mirrors/ex/execa点击查看免费下载本文是 execaProcess execution for humans输出Output能力的实战指南围绕官方文档 docs/output.md 展开。你将学会用stdout/stderr选项把子进程输出重定向到终端、文件、文件描述符乃至任意类型对象用all选项获取与终端一致的stdout/stderr交错输出用stdio数组管理额外文件描述符并通过maxBuffer、buffer等选项在拿到完整结果与节约内存之间做出取舍。读完即可在自己的脚本、CLI 工具或库中精准控制 execa 的每一路输出。基础用result.stdout/result.stderr读取子进程输出stdout与stderr选项决定子进程的标准输出与标准错误如何被处理它们默认都是pipe——即把输出通过管道收集起来待子进程结束后以 result.stdout 和 result.stderr 属性的形式返回给你import {execa} from execa; const {stdout, stderr} await execanpm run build; console.log(stdout); console.log(stderr);模板字符串语法execa\command args在这里与execa(command, [args])等价。需要说明的是result.stdout/result.stderr只是result.stdio[1]/result.stdio[2]的便捷别名——从源码 [lib/return/result.js](https://link.gitcode.com/i/fd3b2264ec8186605f3dd336708d317e) 可以看到无论成功还是失败结果对象都通过stdout: stdio[1], stderr: stdio[2] 这样的方式装配。默认pipe行为的底层规范化逻辑位于 lib/stdio/stdio-option.js当某个选项值为null或undefined时标准输入/输出/错误fd 0、1、2默认填pipe而额外文件描述符fd 3默认填ignore。忽略输出ignore如果你不关心子进程打印了什么可以显式忽略避免管道阻塞或内存浪费const {stdout, stderr} await execa({stdout: ignore})npm run build; console.log(stdout); // undefined console.log(stderr); // string with errors注意这里只忽略了stdoutstderr仍是默认的pipe所以stderr里依然能拿到错误信息。这个用法在只要退出码、不要输出的场景比如 CI 里执行静默检查非常常见。重定向到文件{file}对象与文件 URL把输出直接写进文件可以用{file: 路径}对象或文件 URLawait execa({stdout: {file: output.txt}})npm run build; // 或者 await execa({stdout: new URL(file:///path/to/output.txt)})npm run build;也可以让stdout与stderr交错地重定向到同一个文件这在日志收集中很实用// 将交错出现的 stdout 和 stderr 重定向到同一个文件 const output {file: output.txt}; await execa({stdout: output, stderr: output})npm run build;默认是覆盖写overwrite如需追加模式加上append: true// 追加而不是覆盖 await execa({stdout: {file: output.txt, append: true}})npm run build;从类型检测源码 lib/stdio/type.js 可以看出{file, append}这种文件路径对象是 execa 识别的一类独立输入类型filePath文件 URLfileUrl同样单独识别。这两类值在 lib/stdio/type.js 中被归入FILE_TYPES并且当两个文件描述符共享同一文件目标时还会触发 SPECIAL_DUPLICATE_TYPES 的特殊逻辑来保证交错写入同一文件的正确性。终端输出inherit、文件描述符编号与 Node.js 流CLI 应用里最常用的需求是让子进程直接复用父进程的终端输出。把选项设为inherit即可子进程会直接继承父进程的输出句柄效果等价于直接打印到终端await execa({stdout: inherit, stderr: inherit})npm run build;如果想重定向到不同的文件描述符可以传文件描述符编号或传process.stdout/process.stderr这类 Node.js 流对象// 把 stdout 和 stderr 都打印到父进程的 stdout await execa({stdout: process.stdout, stderr: process.stdout})npm run build; // 或者 await execa({stdout: 1, stderr: 1})npm run build;其中1是标准输出stdout的文件描述符编号2是标准错误stderr。这类原生 Node.js 流native类型同样由 lib/stdio/type.js 的isStream检测兜底识别。返回任意类型IPC 与result.ipcOutput如果子进程本身是 Node.js 文件可以开启 IPC 能力让子进程通过sendMessage()回传几乎任意类型的消息对象、数组、日期等主进程通过 result.ipcOutput 数组按发送顺序读取// main.js import {execaNode} from execa; const {ipcOutput} await execaNodebuild.js; console.log(ipcOutput[0]); // {kind: start, timestamp: date} console.log(ipcOutput[1]); // {kind: stop, timestamp: date}// build.js import {sendMessage} from execa; await sendMessage({kind: start, timestamp: new Date()}); await runBuild(); await sendMessage({kind: stop, timestamp: new Date()});这是 execa 区别于普通child_process的招牌能力进程间的输出不再局限于文本而是结构化的消息。result.ipcOutput字段在 lib/return/result.js 中随结果一并返回失败时也会出现在错误对象的同名属性里。关于消息类型与收发 API 的细节见 docs/ipc.md。多重目标把一路输出同时送到多个地方stdout或stderr可以是一个数组把同一路输出同时重定向到多个目标。下面的例子把stdout同时送往终端、output.txt文件并继续通过管道在程序里取值const {stdout} await execa({stdout: [inherit, {file: output.txt}, pipe]})npm run build; console.log(stdout);TTY 控制的损失请注意当一个文件描述符被配置为inherit与其他值的组合时该文件描述符在子进程中永远不会指向 TTY即使在当前进程中它确实指向 TTY。也就是说数组组合会让子进程检测不到自己连接在交互终端上在需要 TTY 行为如颜色输出、交互式提示时需特别注意。底层实现上每个数组项都会被 normalizeStdioOption 独立展开为对应的 stdio 条目处理。交错输出all选项终端上stdout和stderr是交错打印的但管道收集时两者是分开的。设置all: true后execa 会把两者合并result.all等价于result.stdoutresult.stderrsubprocess.all等价于subprocess.stdoutsubprocess.stderrconst {all} await execa({all: true})node example.js;// example.js console.log(1); // writes to stdout console.error(2); // writes to stderr console.log(3); // writes to stdoutstdout与stderr保证会交错但由于性能原因子进程可能把多次对同一流的连续写入缓冲、合并成一次写入从而破坏交错顺序。例如上面这个例子可能打印出1 3 2而不是1 2 3因为两次console.log()被合并成了同一次写入。一个绕开办法是让两次 stdout 写入之间先让出事件循环import {setTimeout} from timers/promises; console.log(1); console.error(2); await setTimeout(0); console.log(3);从实现看all流通过sindresorhus/merge-streams把stdout与stderr两个可读流合并而成见 lib/resolve/all-async.js等待其结束时会以fdNumber: all的身份读取内容并把maxBuffer按stdout与stderr之和maxBuffer[1] maxBuffer[2]计算lib/resolve/all-async.js。按文件描述符配置的输出选项有一组选项专门作用于子进程输出verbose、lines、stripFinalNewline、buffer、maxBuffer。默认情况下它们作用于所有文件描述符stdout、stderr以及 fd3 等额外描述符和 IPC 消息但也可以传一个普通对象只对stdout、stderr、allstdoutstderr 合并、ipc、fd3等分别生效// stdout 和 stderr 使用同一个值 await execa({verbose: full})npm run build; // stdout 和 stderr 使用不同的值 await execa({verbose: {stdout: none, stderr: full}})npm run build;从源码看这五个选项被统一登记在 lib/arguments/specific.js 的FD_SPECIFIC_OPTIONS [lines, buffer, maxBuffer, verbose, stripFinalNewline]中。规范化时普通值会填充到所有 fd 上而对象形式则按键stdout/stderr/all/ipc/fd3…逐一映射到对应 fd 下标例如{verbose: {stdout: none, stderr: full}}会变成{verbose: [none, none, full]}见 lib/arguments/specific.js 的注释。默认值也在 DEFAULT_OPTIONS 中集中定义lines: false、buffer: true、maxBuffer: 1000 * 1000 * 100即 100MB、verbose: none调试 execa 自身时则为full、stripFinalNewline: true。额外文件描述符stdio数组stdio选项是一个数组把stdin、stdout、stderr和任意其他文件描述符组合在一起。当子进程用到标准三个之外的额外文件描述符用于输入或输出时非常有用例如{stdio: [pipe, pipe, pipe, pipe]}就会额外创建一个 fd3 管道。result.stdio 可以按数组下标读取任意文件描述符的输出而不只限于stdout和stderr// 从文件描述符编号 3 读取输出 const {stdio} await execa({ stdio: [pipe, pipe, pipe, pipe], })npm run build; console.log(stdio[3]);注意数组可以超过 3 项用于创建额外文件描述符。对于 fd3某些值的读写方向有歧义如pipe、inherit、文件、变换器默认按输出处理若想用作输入需要包成{value, input: true}见 docs/api.md 与 docs/input.md 的额外文件描述符一节。规范化逻辑 getStdioArray 会保证数组长度不小于 3空缺位置自动补默认值。快捷方式stdio单值stdio选项也可以是单个值pipe、overlapped见 docs/windows.md 异步 IO 一节、ignore或inherit。这是把同一个值同时赋给stdin、stdout、stderr的快捷写法await execa({stdio: ignore})npm run build; // 等价于 await execa({stdin: ignore, stdout: ignore, stderr: ignore})npm run build;这个展开逻辑在 getStdioArray 中实现当stdio是字符串时直接[stdio, stdio, stdio]。同时要注意stdio不能与stdin/stdout/stderr中的任何一个同时使用否则会抛出明确错误lib/stdio/stdio-option.js。大输出防护maxBuffer与error.isMaxBuffer为了防止高内存消耗可以用maxBuffer设置输出上限默认100MB即100_000_000。当达到阈值时子进程会以失败告终且 error.isMaxBuffer 变为true此时被截断的部分输出仍然可以通过error.stdout、error.stderr和error.ipcOutput读取try { await execa({maxBuffer: 1_000_000})npm run build; } catch (error) { if (error.isMaxBuffer) { console.error(Error: output larger than 1MB.); console.error(error.stdout); console.error(error.stderr); } throw error; }maxBuffer的计量单位取决于你使用的输出模式默认按字符数String.length计量若encoding为buffer按字节计量若lines为true按行数计量若使用了对象模式的变换器按对象数计量对于error.ipcOutput检索全部消息按消息条数计量。这一单位判定逻辑在 lib/io/max-buffer.js 中一目了然readableObjectMode → objects、lines → lines、encoding buffer → bytes、否则characters。触发时内部会抛出MaxBufferError来自get-stream销毁对应流并把fdNumber与单位信息挂到error.maxBufferInfo上用于构造错误消息lib/io/max-buffer.js错误文本形如Commands stdout was larger than 1000000 characters。IPC 输出result.ipcOutput同样受maxBuffer约束达到上限即按messages单位报错lib/io/max-buffer.js。作为对比同步方法execaSync无法按 fd 分别限制只能利用 Node.js 原生spawnSync的maxBuffer此时命中上限会抛出ENOBUFS错误由 isMaxBufferSync / truncateMaxBufferSync 负责识别并截断结果。低内存模式buffer: false当buffer为false时result.stdout、result.stderr、result.all、result.stdio[*]与result.ipcOutput这些属性都是空的不收集。这能在输出很大时避免高内存消耗但代价是输出必须被忽略、重定向到文件、流式处理见 docs/streams.md或通过 IPC 监听见 docs/ipc.md。如果选择流式处理应当立即开始读取subprocess.stdout等流以免错过任何数据——这正是 lib/io/contents.js 中resumeStream()存在的意义当buffer: false时若流尚未进入 flowing 状态execa 会在一个setImmediate后主动resume()它确保数据不会因为没人消费而滞留。另外还有一个与同步方法相关的细节lib/stdio/stdio-option.js同步方法配合buffer: false时除非输出确实被需要例如verbose: full或重定向到文件stdout/stderr会被隐式改成ignore从而真正省下内存。小结围绕输出这一主题execas 提供了从简单到高级的完整链路pipe程序化取值→ignore丢弃→{file}/文件 URL落盘→inherit/fd 编号/Node 流终端与自定义句柄→ 数组多目标→all交错合并→stdio多 fd→buffer: falsemaxBuffer内存控制→ IPC任意类型。配合 docs/api.md 中options.stdout、options.stderr、options.stdio、options.all、options.maxBuffer、options.buffer、options.verbose、options.lines、options.stripFinalNewline等条目以及 docs/streams.md、docs/lines.md、docs/binary.md、docs/ipc.md、docs/transform.md 等相邻章节你可以把子进程的每一路输出都收放自如。赞分享开发工具【免费下载链接】execaProcess execution for humans项目地址https://gitcode.com/gh_mirrors/ex/execa点击查看免费下载相关推荐curl --stderr 选项详解重定向错误与诊断输出到指定文件curl stderr 选项详解重定向错误与诊断输出到指定文件 stderr 是 curl 命令行工具中一个被低估的全局选项它可以把 curl 写入标准错误CLI网络通信解决常见问题Snowflake Connector for Python错误处理与调试技巧解决常见问题Snowflake Connector for Python错误处理与调试技巧 Snowflake Connector for Python 是连Execa 二进制数据处理指南从 Uint8Array 输入、buffer 输出到流式与变换Execa 二进制数据处理指南从 Uint8Array 输入、buffer 输出到流式与变换 导读 Execa https://link.gitcode.co开发工具上一篇高效解决Google Drive下载难题3分钟掌握智能下载技巧下一篇微信红包自动抢包助手20243分钟搞定配置手速提升30倍创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考