Node.js: самый простой способ записать стандартный вывод в строковую переменную - PullRequest
0 голосов
/ 18 октября 2018

У меня есть следующий код:

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
});

Я пытаюсь записать окончательные данные в строку, где комментарий находится в третьей-последней строке.

Я изучил потоки, буферные объекты и т. Д., И у меня ничего не получилось (может, я их неправильно делал), поэтому я ищу новое решение, которое будет работать или простое - его невозможно».

РЕДАКТИРОВАТЬ: допустим, что код пересмотрен:

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?

Заранее спасибо за помощь!

1 Ответ

0 голосов
/ 18 октября 2018

Вы можете добавить все фрагменты событий данных в одну строку и сделать с ней что-нибудь, когда канал завершится следующим образом:

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 начинается как пустая строка и каждый раз, когда появляется data событие (обычно более одного раза), вы можете добавлять данные к этой строке, пока весь процесс не будет exit ed.Как только процесс exit s, у вас будет общий stdout вывод.

Также для вашего скрипта может быть проще использовать один единственный вызов spawn и команду sh для соединения всехиз них вместе с конвейерами unix вне node.js.В сочетании с вышесказанным это будет выглядеть так:

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);
});

И если вам все еще нужны отдельные 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);
});

Я обнаружил, что это локально подвержено ошибкам, потому что процесс может завершиться до того, как каналы могут быть подключены (например, grep любит получать информацию, что он должен слушать stdin с чем-то вроде grep -f - в противном случае он выходит с кодом состояния 1).Кроме того, каждый канал может иметь stderr data событий, которые вы должны слушать.Это то, что нужно для обработки всех каналов вместе.

Строка grep может также быть проще, если она работает в вашей системе, grep '3000.*ESTABLISHED' вместо двух вызовов grep.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...