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 badges2 Answers
Reset to default 9 +100You 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
$