Logging script data with Node child_process
Question: I am working with a python script that runs on a loop and outputs a new value
every second, and can only be stopped by pressing `enter` on the keyboard. For
various reasons, the python code should not be altered.

**Ask:** How do I capture the first ten values of the looping script then kill
the script from Node?

I wrote the below Node script that will kick off an external program and log
the output; however, this only works for scripts that aren't running in loops.

    
    
    var exec = require('child_process').exec;
    var scriptCommand = "sudo python script.py"
    
    exec(scriptCommand, function cb(error, stdout, stderr){
      console.log('stdout: ' + stdout);
      console.log('stderr: ' + stderr); 
      if (error !== null){
        console.log('exec error: ' + error);
      }
    });
    


Answer: You're going to want to use spawn and capture the standard output of the
python child process. Once you have reached ten values, you can kill the
python process.

Unfortunately you're going to have to modify the python program to flush
stout. There is no way around this. If you do not manually flush stdout,
python will, but only after the internal buffer fills up (which in my sample
code will take awhile).

Here is a fully working example (captures first three values and then kills
the python process):

**pyscript.py**

    
    
    #!/usr/bin/env python
    # python 2.7.4
    import time
    import sys
    
    i = 0
    while(True):
        time.sleep(1)
        print("hello " + str(i))
    
        # Important! This will flush the stdout buffer so node can use it
        # immediately. If you do not use this, node will see the data only after
        # python decides to flush it on it's own.
        sys.stdout.flush()
    
        i += 1
    

**script.js**

    
    
    #!/usr/bin/env node
    "use strict";
    // node version 0.10.26
    
    var spawn = require('child_process').spawn
    , path = require('path')
    , split = require('split');
    
    // start the pyscript program
    var pyscript = spawn('python', [ path.join(__dirname, 'pyscript.py') ]);
    
    var pythonData = [];
    
    // Will get called every time the python program outputs a new line.
    // I'm using the split module (npm) to get back the results
    // on a line-by-line basis
    pyscript.stdout.pipe(split()).on('data', function(lineChunk) {
        // Kill the python process after we have three results (in our case, lines)
        if (pythonData.length >= 3) {
            return pyscript.kill();
        }
    
        console.log('python data:', lineChunk.toString());
        pythonData.push(lineChunk.toString());
    });
    
    // Will be called when the python process ends, or is killed
    pyscript.on('close', function(code) {
        console.log(pythonData);
    });
    

Put them both in the same directory, and make sure to grab the
[split](https://www.npmjs.org/package/split) module for the demo to work.

