help
help copied to clipboard
child_process.exec wrong output order
Details
Good day, I am currently trying to execute commands with child_process.exec, which also works. However, I get 3 different outputs and would need 1 which outputs everything in the correct order. For example, when I run the script from below I get the following:
test1
test2
test3
test4
test5
test6
test7
test8
test9
test10
./script.sh: 6: ./script.sh: dfgyfhgdtfgsdfsdf: not found
The correct order would actually be:
test1
test2
test3
test4
test5
./script.sh: line 6: dfgyfhgdtfgsdfsdf: command not found
test6
test7
test8
test9
test10
Does anyone have an idea how to change this?
Node.js version
16.13.1
Example code
Code:
const { exec } = require("child_process");
const command = './script.sh';
if(command !== undefined){
exec(command, (error, stdout, stderr) => {
console.log(error);
console.log(stdout);
console.log(stderr);
});
}else{
console.log('no command');
}
Script:
echo test1;
echo test2;
echo test3;
echo test4;
echo test5;
dfgyfhgdtfgsdfsdf;
echo test6;
echo test7;
echo test8;
echo test9;
echo test10;
Operating system
node docker image
Scope
code
Module and version
Not applicable.
Thanks for creating this issue. I found an answer from stackoverflow
$ cat test.js
const { spawn } = require('child_process');
const child = spawn('./script.sh', ['2>&1'], { shell: true });
let mergedOut = '';
child.stdout.on('data', (chunk) => {
process.stdout.write(chunk);
mergedOut += chunk;
});
child.on('close', (_code, _signal) => {
console.log('-'.repeat(30));
console.log(mergedOut);
});
$ node test.js
test1
test2
test3
test4
test5
./script.sh: line 6: dfgyfhgdtfgsdfsdf: command not found
test6
test7
test8
test9
test10
------------------------------
test1
test2
test3
test4
test5
./script.sh: line 6: dfgyfhgdtfgsdfsdf: command not found
test6
test7
test8
test9
test10
execa say it could achieve that, but I don't make it works. Maybe you can give it another try.
This package improves child_process methods with:
- Get interleaved output from stdout and stderr similar to what is printed on the terminal. (Async only)
$ npm ls execa
[email protected] /Users/feng/test
└── [email protected]
$ cat test.mjs
import {execa} from 'execa';
const { all } = await execa('./script.sh', {all: true });
console.log(all);
$ node test.mjs
test1
test2
test3
test4
test5
test6
test7
test8
test9
test10
./script.sh: line 6: dfgyfhgdtfgsdfsdf: command not found
execa say it could achieve that, but I don't make it works. Maybe you can give it another try.
I made an issue for this problem: https://github.com/sindresorhus/execa/issues/502
There has been no activity on this issue for 11 months. The help repository works best when sustained engagement moves conversation forward. The issue will be closed in 1 month. If you are still experiencing this issue on the latest supported versions of Node.js, please leave a comment.
Closing after no activity on this issue for 12 months.
Just to clarify, is it still possible to anyhow force-order the data event handling of stdout and stderr in the actual stream order? Currently, the same issue persists.
Example
// File 'stdio.c'
#include<stdio.h>
int main ( ) {
printf("OUT1\n");
fprintf(stderr, "ERR1\n");
printf("OUT2\n");
return 0;
}
// File 'stdio.js'
const { spawn } = require('node:child_process');
const child = spawn('./stdio; echo ERR2 >&2; echo OUT3;', [], { shell: true });
child.stdout.on('data', (data) => { process.stdout.write(data); });
child.stderr.on('data', (data) => { process.stdout.write(data); });
child.on('close', () => { process.exit(); });
$ g++ -o stdio ./stdio.c;
$ node --version
v22.3.0
$ node ./stdio.js;
OUT1
OUT2
OUT3
ERR1
ERR2