Node.js使用child_process执行shell命令时如何支持ISO-8859-1编码
Node.js child_process 模块使用 ISO-8859-1 编码的可行方案
Node.js 调用 shell 命令时不会强制使用 UTF-8 编码,出现适配问题的核心原因是:child_process 系列 API 默认会用 UTF-8 规则将子进程输入输出的原始字节流自动解码为 JS 字符串,遇到 ISO-8859-1 专属字符时就会出现乱码,通过以下方式即可完美适配 ISO-8859-1 场景:
核心实现思路
关闭默认的自动字符串解码逻辑,拿到原始二进制 Buffer 后,手动使用 ISO-8859-1 规则做编解码即可。Node.js 原生支持 ISO-8859-1 编解码,对应的编码标识为 latin1,和 ISO-8859-1 标准完全等价,无需引入第三方依赖。
具体实现示例
- 异步 spawn 场景
const { spawn } = require('child_process'); // 启动子进程时指定 encoding 为 buffer,关闭自动 UTF-8 解码 const child = spawn('目标shell命令', ['参数1', '参数2'], { encoding: 'buffer', // 按需配置 shell: true 等其他参数 }); const stdoutChunks = []; const stderrChunks = []; child.stdout.on('data', chunk => stdoutChunks.push(chunk)); child.stderr.on('data', chunk => stderrChunks.push(chunk)); child.on('close', exitCode => { // 拼接原始字节流,用latin1解码得到正确的ISO-8859-1文本 const stdout = Buffer.concat(stdoutChunks).toString('latin1'); const stderr = Buffer.concat(stderrChunks).toString('latin1'); console.log('标准输出:', stdout); console.log('标准错误:', stderr); console.log('进程退出码:', exitCode); }); // 如果需要向子进程stdin写入ISO-8859-1内容,先转成Buffer再写入 const inputContent = '需要传入子进程的文本'; child.stdin.write(Buffer.from(inputContent, 'latin1')); child.stdin.end();
- 异步 exec 场景
const { exec } = require('child_process'); exec('目标shell命令', { encoding: 'buffer' }, (err, stdoutBuf, stderrBuf) => { const stdout = stdoutBuf.toString('latin1'); const stderr = stderrBuf.toString('latin1'); // 后续业务处理 });
- 同步方法场景(execSync/spawnSync 通用)
const { execSync } = require('child_process'); const outputBuf = execSync('目标shell命令', { encoding: 'buffer' }); // 手动解码为ISO-8859-1文本 const output = outputBuf.toString('latin1');
注意点
不推荐直接在 child_process 的配置项中传入 encoding: 'latin1' 依赖自动解码,部分 Node.js 旧版本对该配置的流解码支持存在兼容问题,手动操作 Buffer 解码的方案在所有 LTS 版本中均可稳定运行。
内容的提问来源于stack exchange,提问作者Felipe Augusto Gonalves Basili
相关产品推荐
相关产品推荐

