help icon indicating copy to clipboard operation
help copied to clipboard

child_process.exec wrong output order

Open sb2050 opened this issue 3 years ago • 3 comments

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.

sb2050 avatar May 13 '22 15:05 sb2050

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:

$ 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

F3n67u avatar Jun 12 '22 05:06 F3n67u

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

F3n67u avatar Jun 12 '22 06:06 F3n67u

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.

github-actions[bot] avatar Mar 11 '24 01:03 github-actions[bot]

Closing after no activity on this issue for 12 months.

github-actions[bot] avatar Apr 10 '24 01:04 github-actions[bot]

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

serious-angel avatar Jun 13 '24 17:06 serious-angel