最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to prefix every line of the output of a child_process spawn() call with text? - Stack Overflow

programmeradmin1浏览0评论

I execute several processes using spawn() from child_process.

const { spawn } = require('child_process');

spawn("sh", ["script1.sh"], { shell: false, stdio: "inherit"});
spawn("sh", ["script2.sh"], { shell: false, stdio: "inherit"});
spawn("sh", ["script3.sh"], { shell: false, stdio: "inherit"});

Question: How to prefix the output of the scripts with text?

The idea is that I would be able to easily distinguish what each script logs.

I went through the spawn documentation but couldn't find anything that would help achieve this.

Note: I cannot modify the scripts.

I execute several processes using spawn() from child_process.

const { spawn } = require('child_process');

spawn("sh", ["script1.sh"], { shell: false, stdio: "inherit"});
spawn("sh", ["script2.sh"], { shell: false, stdio: "inherit"});
spawn("sh", ["script3.sh"], { shell: false, stdio: "inherit"});

Question: How to prefix the output of the scripts with text?

The idea is that I would be able to easily distinguish what each script logs.

I went through the spawn documentation but couldn't find anything that would help achieve this.

Note: I cannot modify the scripts.

Share Improve this question edited Dec 3, 2020 at 20:36 Sasha Shpota asked Dec 1, 2020 at 14:23 Sasha ShpotaSasha Shpota 10.3k15 gold badges93 silver badges176 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 9 +100

You have stdio set to "inherit".

If you set this to "pipe", Node.js will give you back readable streams for stderr and stdin, which you can use to add your prefix.

const { spawn } = require('child_process');

const one = spawn("sh", ["script1.sh"], { shell: false, stdio: "pipe"});
let oneStdout = ''
one.stdout.on('data', function (chunk) {
  oneStdout += chunk
  const lines = oneStdout.split('\n')
  while(lines.length > 1) {
    const line = lines.shift()
    console.log('one',line)
  }
  oneStdout = lines.shift()
})
one.stdout.on('end', function () {
  console.log('one', oneStdout)
})

Here is the relevant section in the docs: https://nodejs/api/child_process.html#child_process_subprocess_stdio

Potential gotcha:

When "prefixing" you likely want to prefix each new line but not all scripts write to stdout a full line at a time. Play around with a few scripts that use echo -n "foobar" throughout the output to test that you're handling line breaks correctly.

Here is how I run external mands and capture their output, e.g. to prefix each line with a timestamp:

const { spawn } = require("child_process"),
  mand = "echo",
  args = ["Studies have shown that people watch TV more than any other appliance."];

const child = spawn(mand, args);

child.stdout.on('data', buff => {
  const line = buff.toLocaleString();
  console.info(new Date(), line);
});
child.stderr.on('data', buff => { // also catch any error output
  const line = buff.toLocaleString();
  console.error(new Date(), line);
});
child.on('exit', code => {console.info(`Command exited with code ${code}`)});

Here's what it looks like when you run it:

$ node thatScript.js 
2020-12-10T11:46:51.455Z Studies have shown that people watch TV more than any other appliance.

Command exited with code 0
$ 
发布评论

评论列表(0)

  1. 暂无评论