Search code examples
node.jsprocessspawn

Cannot pipe stdout from spawn for a specific application


I have two scripts A.js and B.js, and a 3rd party application (which is open source). Script A.js launches the 3rd party application using execSync. Script B.js launches script A.js using spawn.

If I run script A.js by itself, I can see the entire output of the 3rd party app. When I run it indirectly by running script B.js, I can only see some of the output.

A.js

const { execSync } = require('child_process');
console.log("Hello");
execSync('mybinary.exe -arg1 -arg2', { stdio: 'inherit' });

B.js

const { spawn } = require('child_process');
const app = spawn(process.execPath, ['A.js'], {
  stdio: ['inherit', null, 'inherit']
});

app.stdout.on('data', (chunk) => {
  process.stdout.write(chunk);
});

When I launch B, I only see "Hello", however the binary is running (it's a server and I can open a TCP connection to it). I'm just not seeing the output. When I launch A by itself, I see both "Hello" and the regular binary's output.

If I change B's stdout to 'inherit', it works.

Why is this happening, and how do I fix this?

UPDATE: Doesn't seem to have anything to do with the use of two scripts. Spawning the binary directly without using stdio inherit exhibits the same issue. Seems to be dependant on the third party application. How could a program affect node if it just prints to stdout?

CONTEXT: I want to launch a server and then run a command when the server is ready. When ready, the server prints out a particular message. The idea was to wait for this message to be printed. After printing out this message, it doesn't print out anything else, but it stays running.

The particular executable I'm attempting to pipe is a ChatScript server.

UPDATE: At this point, I assume it's something with the specific binary I'm attempting to pipe. I want to understand how the binary can affect this behaviour, i.e. works with inherit but not pipe. If someone can recreate this behaviour with a node script (or c program), that will answer the question.


Environment

  • OS: Windows 10
  • Console: Cygwin (and also tried regular Command Prompt).
  • Node v7.10.0

Note that this is the same issue as here: node.js child_process.spawn no stdout unless 'inherit'


Solution

  • The writes that chatscript is doing are 'fprintf( stdout, ...)' This is a buffered output, and is saved until like (4k?) is buffered and then flushed. Adding 'fflush(stdout)' after a fprintf( stdout ) in ChatScript/src/os.cpp line 1849 for instance... then output works (somewhat, further changes will be required, but I did get at least 'in cs_init.txt' errors logging now.

    Another test is just to redirect chatscript.exe to a file and see what the file gets. 'chatscript > zz' and then ending chatscript with ctrl-c you'll see that zz is blank also... this is an indication that the IO has been buffered and not flushed to output appropriately.

    M:\javascript\test_exec>node b.js
    Hello
    
       in cs_init.txt at 0:
         A subdirectory or file USERS already exists.
    Error opening utf8writeappend file LOGS/startlog.txt: No such file or     directory
    ChatScript Release Version 7.5 pid: 0 32 bit Windows compiled Jun 24 2017 09:42:13 host=local
    Params:   dict:2097151 fact:800000 text:100000kb hash:215127
              buffer:80x80kb cache:1x5000kb userfacts:100 outputlimit:80000     loglimit:80000
    Unable to read dictionarySystem.h
    Missing 37 word files
    read 0 raw words
    
       in facts.txt at 0:
        A subdirectory or file USERS already exists.