首页 > 解决方案 > 在cmd中使用node.js执行'tracert',但我的输出不一致

问题描述

我正在尝试编写一个在 cmd 中执行 tracert 的 node.js 脚本,我想解析 tracert 的输出以便能够在 node.js 中使用。我的问题是我收到的输出并不一致。

let argument = process.argv[2] /* what the user enters as first argument */

const { spawn } = require('child_process');
const command = spawn(process.env.comspec, ['/c', 'tracert', argument])

command.stdout.on('data', (data) => {
    console.log(`stdout: ${data}`);
});

tracert 在每一行上以这种格式输出,对于每一跳。

1    5 ms     6 ms     4 ms     192.168.1.1

console.log 的预期输出应该是:

stdout: 1
stdout: 5 ms
stdout: 6 ms
stdout: 4 ms
stdout: 192.168.1.1

事实上,这就是大约 90% 的时间发生的事情,但有时数据来得如此之快,以至于一些行像这样在同一行上聚集在一起

stdout: 1
stdout: 5 ms
stdout: 6 ms 4 ms
stdout: 192.168.1.1

我不希望这种情况发生。我希望每次数据变量进入时,它只包含每个“列”中的“一个元素”

标签: node.js

解决方案


不幸的是,您不能强制tracert逐列发送数据。此外,当您的进程不足以从管道中读取它们时,您不能强制操作系统,而不是“加入”缓冲区中的列。

唯一可能的解决方案是等到整行准备好,然后才解析它。Stg 像这样(警告,这只是伪代码)。

let bufffer = "";
command.stdout.on('data', (data) => {
    buffer = buffer + data;
    while (buffer.indexOf('\n') != -1) { // loop because in some cases you can even receive many lines
         const idx = buffer.indexOf('\n');
         const line = buffer.substr(0, idx).trim(); // get line and trim extra whitespace
         buffer = buffer.substr(idx+1); // rest of buffer, usually empty string

         // now parse line with regexp or something
         const match = /(\d+) (\d+) ms +(\d+) ms +(\d+) ms ([^ ]+)/.match(line);
         if (match) {
             ...
         }
    }
});

推荐阅读