如何使用Node.js的child_process监听bat脚本运行时输出的特定关键词?
Node.js 监听Windows .bat脚本实时输出的实现方案
你可以直接通过child_process返回的子进程实例监听标准输出流,无需等待脚本进程退出就能实时匹配输出关键词,以下是适配你现有代码的修改方案:
基础实现代码
const { exec } = require('child_process'); // 接收exec返回的子进程实例 const batProcess = exec('D:\\servers\\game_server_1\\start.bat', { shell: true, cwd: 'D:\\servers\\game_server_1' }); // 加标记防止重复触发通知 let notified = false; // 监听脚本的标准输出流 batProcess.stdout.on('data', (chunk) => { // 将输出流转为字符串,Windows下如果出现乱码可以看后面的编码适配方案 const output = chunk.toString(); // 可选:打印全量输出方便排查问题 console.log('脚本实时输出:', output); // 匹配目标关键词 if (!notified && output.includes('Done!')) { notified = true; // 此处写入你要执行的后续逻辑:推送服务器启动成功通知 console.log('检测到启动完成信号,推送通知'); } }); // 监听脚本的错误输出流,方便排查脚本运行报错 batProcess.stderr.on('data', (errChunk) => { console.error('脚本错误输出:', errChunk.toString()); }); // 可选:监听脚本进程退出事件 batProcess.on('exit', (code) => { console.log('脚本进程已退出,退出码:', code); });
优化适配方案
解决输出内容拆分导致匹配失效的问题
如果脚本输出量大,可能出现一次data事件返回多段内容、或者关键词被拆分到两次data事件中的情况,可通过缓冲区按行匹配保证准确率:
let buffer = ''; let notified = false; batProcess.stdout.on('data', (chunk) => { buffer += chunk.toString(); // 按Windows换行符拆分内容 const lines = buffer.split(/\r?\n/); // 保留最后一段不完整的内容到下一次处理 buffer = lines.pop(); lines.forEach(line => { if (!notified && line.trim().includes('Done!')) { notified = true; // 执行通知逻辑 } }); });
Windows输出乱码适配
Windows cmd默认输出编码为GBK,直接调用toString()会出现中文乱码,可通过iconv-lite转码解决:
- 先安装依赖:
npm install iconv-lite - 修改exec配置和转码逻辑:
const iconv = require('iconv-lite'); const batProcess = exec('D:\\servers\\game_server_1\\start.bat', { shell: true, cwd: 'D:\\servers\\game_server_1', encoding: 'buffer' // 指定返回buffer类型用于转码 }); batProcess.stdout.on('data', (chunk) => { const output = iconv.decode(chunk, 'gbk'); // 后续匹配逻辑和上面一致 });
可选替换方案
如果后续需要对子进程做更复杂的交互(比如发送指令),可以把exec替换为spawn,输出监听的逻辑完全一致,仅初始化代码不同:
const { spawn } = require('child_process'); const batProcess = spawn('start.bat', [], { shell: true, cwd: 'D:\\servers\\game_server_1' });
内容的提问来源于stack exchange,提问作者Happy Lama
相关产品推荐
相关产品推荐

