如何在Electron中解析wsl --list --verbose输出实现WSL状态展示
解析WSL实例状态输出并生成结构化数据
需求背景
要实现类似Docker Desktop左下角展示WSL实例状态(运行/停止)的功能,需解析wsl --list --verbose命令的输出。
现有Electron代码
ipcMain.on('cmd', async (event, arg)=>{ const execute = (command, callback)=>{ exec(command, (error, stdout, stderr) => { callback(stdout); }); }; // call the function execute('wsl --list --verbose', (output) => { event.sender.send('cmd-callback',output) }); })
当前问题
尝试用args.split(/[\r\n|\n|\r]/).filter(String)分割输出时,结果包含大量\u0000空字符,无法提取结构化数据,当前输出如下:
[ " \u0000 \u0000N\u0000A\u0000M\u0000E\u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000S\u0000T\u0000A\u0000T\u0000E\u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000V\u0000E\u0000R\u0000S\u0000I\u0000O\u0000N\u0000", "\u0000", "\u0000*\u0000 \u0000U\u0000b\u0000u\u0000n\u0000t\u0000u\u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000S\u0000t\u0000o\u0000p\u0000p\u0000e\u0000d\u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u00002\u0000", "\u0000", "\u0000 \u0000 \u0000d\u0000o\u0000c\u0000k\u0000e\u0000r\u0000-\u0000d\u0000e\u0000s\u0000k\u0000t\u0000o\u0000p\u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000S\u0000t\u0000o\u0000p\u0000p\u0000e\u0000d\u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u00002\u0000", "\u0000", "\u0000 \u0000 \u0000d\u0000o\u0000c\u0000k\u0000e\u0000r\u0000-\u0000d\u0000e\u0000s\u0000k\u0000t\u0000o\u0000p\u0000-\u0000d\u0000a\u0000t\u0000a\u0000 \u0000 \u0000 \u0000 \u0000S\u0000t\u0000o\u0000p\u0000p\u0000e\u0000d\u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u0000 \u00002\u0000", "\u0000", "\u0000" ]
期望结果
得到结构化的JavaScript数组:
[ ['Ubuntu', 'Stopped', '2'], ['docker-desktop', 'Stopped', '2'], ['docker-desktop-data', 'Stopped', '2'], ]
解决方案
问题根源是Windows下wsl命令输出采用UTF-16LE编码,而Node.js的exec默认用UTF-8解析,导致出现\u0000空字符。解决步骤如下:
- 修正编码解析:在调用
exec时指定编码为utf16le,确保输出字符正常。 - 结构化处理输出:清理空行、跳过标题行,提取每行的实例名称、状态和版本信息。
修改后的完整代码:
const { exec } = require('child_process'); const { ipcMain } = require('electron'); ipcMain.on('cmd', async (event, arg) => { const execute = (command, callback) => { // 指定编码为utf16le,解决Windows下WSL输出的编码问题 exec(command, { encoding: 'utf16le' }, (error, stdout, stderr) => { if (error) { console.error(`执行错误: ${error.message}`); return; } callback(stdout); }); }; execute('wsl --list --verbose', (output) => { // 处理输出:分割行、过滤空行 const lines = output.split(/\r?\n/).filter(line => line.trim() !== ''); // 跳过标题行,处理数据行 const wslInstances = lines.slice(1).map(line => { // 去掉开头的*(默认实例标记),然后按多个空格分割 const parts = line.replace(/^\s*\*/, '').trim().split(/\s{2,}/); // 返回名称、状态、版本 return [parts[0].trim(), parts[1].trim(), parts[2].trim()]; }); event.sender.send('cmd-callback', wslInstances); }); })
代码说明
- 编码修正:通过
{ encoding: 'utf16le' }让exec正确解析WSL的输出,避免\u0000字符。 - 行处理:用
split(/\r?\n/)分割行,过滤掉空行;跳过第一行标题。 - 提取数据:每行先去掉开头的
*标记,再用split(/\s{2,}/)按多个空格分割(因为输出中列之间是多个空格分隔),最后提取前三个有效字段作为实例信息。
内容的提问来源于stack exchange,提问作者SamTV
相关产品推荐
相关产品推荐

