简体   繁体   English

Node.js:将stdout捕获到字符串变量中的最简单方法

[英]Node.js: Easiest way to capture stdout into string variable

I have the following code: 我有以下代码:

const spawn = require("child_process").spawn;

const netStat = spawn('netstat', ['-nat']);
const grepPort = spawn('grep', ['3000']);
const grepStatus = spawn('grep', ['ESTABLISHED']);

console.log('Determining public ip\'s connected to port 3000');

// get port 3000 from netstat
netStat.stdout.on('data', (data) => {
  grepPort.stdin.write(data);
  });

netStat.on('close', (code) => {
  if (code !== 0) {console.log(`netstat process exited with code ${code}`);}
  grepPort.stdin.end();
});

// get ESTABLISHED from port 3000
grepPort.stdout.on('data', (data) => {
  grepStatus.stdin.write(data);
  });

grepPort.on('close', (code) => {
  grepStatus.stdin.end();
});

grepStatus.stdout.on('data', (data) => {
  console.log(data.toString())
  // Store data.toString() to variable here
});

I am trying to capture the final data into a string where the comment is in the 3rd to last line. 我正在尝试将最终数据捕获到一个字符串中,注释位于第三行到最后一行。

I've looked into streams, buffer objects, etc and got nothing to work (maybe I was doing them wrong?) so I'm looking for a fresh solution that will work or a simple "its not possible". 我已经研究了流,缓冲区对象等,但没有任何工作(也许是我做错了吗?),所以我正在寻找可以使用的新解决方案或简单的“不可能”。

EDIT: Lets say the code is revised: 编辑:可以说代码已修改:

const spawn = require("child_process").spawn;
var port = 3000
console.log(`Determining public ip\'s connected to port ${port}`);

let output = '';

const proc = spawn('sh', [
  '-c',
  `netstat -nat | grep ${port}.*ESTABLISHED | awk '{print $5}' | grep -v .*${port}`
]);

proc.stdout.on('data', (chunk) => {
  output += chunk.toString();
});

proc.stderr.on('data', (chunk) => {
  console.log(chunk.toString());
});

proc.on('error', (err) => {
  console.error(err);
});

proc.on('exit', (code) => {
  console.log("Done");
});

console.log(output); // Should print output, no?

Thanks in advance for the help! 先谢谢您的帮助!

You can append all data event chunks onto one single string and do something with it when the pipe ends like so: 您可以将所有数据事件块附加到一个字符串上,并在管道结束时对其进行一些操作,如下所示:

const spawn = require('child_process').spawn;
const proc = spawn('netstat', ['-nat']);

let output = '';
proc.stdout.on('data', (chunk) => {
  output += chunk.toString();
});
proc.on('exit', () => {
  console.log(output);
});

output starts as an empty string and each time there is a data event (more than once, usually) you can append the data to that string until the whole process is exit ed. output从一个空字符串开始,并且每次发生data事件(通常不止一次)时,您都可以将数据附加到该字符串,直到exit整个过程为止。 Once the process exit s, you will have the total stdout output. 流程exit ,您将获得stdout输出的总输出。

Also for your script, it might be easier to use one single spawn call and the sh command to connect all of those together with unix pipes outside of node.js. 同样对于您的脚本,使用一个单独的spawn调用和sh命令将所有这些调用与node.js之外的unix管道连接起来可能会更容易。 That, combined with the above would look like this: 结合以上内容,将如下所示:

const spawn = require("child_process").spawn;

console.log('Determining public ip\'s connected to port 3000');

let output = '';

const proc = spawn('sh', [
  '-c',
  'netstat -nat | grep 3000 | grep ESTABLISHED'
]);

proc.stdout.on('data', (chunk) => {
  output += chunk.toString();
});

proc.stderr.on('data', (chunk) => {
  console.log(chunk.toString());
});

proc.on('error', (err) => {
  console.error(err);
});

proc.on('exit', (code) => {
  console.log(code);
  console.log(output);
});

And if you still want separate spawn s, it may be easier/helpful to use the built-in .pipe methods to connect them together: 如果仍然需要单独的spawn ,使用内置的.pipe方法将它们连接在一起可能会更容易/有用:

const spawn = require("child_process").spawn;

console.log('Determining public ip\'s connected to port 3000');

let output = '';

const netStat = spawn('netstat', ['-nat']);
const grepPort = spawn('grep', ['3000']);
netStat.stdout.pipe(grepPort.stdin);
const grepStatus = spawn('grep', ['ESTABLISHED']);
grepPort.stdout.pipe(grepStatus.stdin);

grepPort.stdout.on('data', (chunk) => {
  output += chunk.toString();
});

netstat.stderr.on('data', (chunk) => {
  console.log(chunk.toString());
});

grepPort.on('error', (err) => {
  console.error(err);
});

grepPort.on('exit', (code) => {
  console.log(code);
  console.log(output);
});

I found this error-prone locally because the process may exit before the pipes can be connected (eg grep likes to be informed it should listen to stdin with something like grep -f - otherwise it exits with status code 1). 我在本地发现了这种容易出错的情况,因为该过程可能在连接管道之前退出了(例如grep喜欢被告知它应该使用grep -f -类的东西监听stdin否则它会以状态代码1退出)。 Additionally, each pipe can have stderr data events that you should listen to. 此外,每个管道可以包含您应该监听的stderr data事件。 That's a to handle so all pipes together might be helpful. 这是可以处理的,因此所有管道一起使用可能会有所帮助。

The grep line could be simpler too if it worked on your system, grep '3000.*ESTABLISHED' instead of two grep invocations. 如果grep行在您的系统上可以更简单,那grep '3000.*ESTABLISHED'而不是两次grep调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM