Exec : display stdout “live”

前端 未结 9 1164
你的背包
你的背包 2020-11-29 15:08

I have this simple script :

var exec = require(\'child_process\').exec;

exec(\'coffee -cw my_file.coffee\', function(error, stdout, stderr) {
    console.lo         


        
相关标签:
9条回答
  • 2020-11-29 15:24

    Here is an async helper function written in typescript that seems to do the trick for me. I guess this will not work for long-lived processes but still might be handy for someone?

    import * as child_process from "child_process";
    
    private async spawn(command: string, args: string[]): Promise<{code: number | null, result: string}> {
        return new Promise((resolve, reject) => {
            const spawn = child_process.spawn(command, args)
            let result: string
            spawn.stdout.on('data', (data: any) => {
                if (result) {
                    reject(Error('Helper function does not work for long lived proccess'))
                }
                result = data.toString()
            })
            spawn.stderr.on('data', (error: any) => {
                reject(Error(error.toString()))
            })
            spawn.on('exit', code => {
                resolve({code, result})
            })
        })
    }
    
    0 讨论(0)
  • 2020-11-29 15:25

    There are already several answers however none of them mention the best (and easiest) way to do this, which is using spawn and the { stdio: 'inherit' } option. It seems to produce the most accurate output, for example when displaying the progress information from a git clone.

    Simply do this:

    var spawn = require('child_process').spawn;
    
    spawn('coffee', ['-cw', 'my_file.coffee'], { stdio: 'inherit' });
    

    Credit to @MorganTouvereyQuilling for pointing this out in this comment.

    0 讨论(0)
  • 2020-11-29 15:28

    Don't use exec. Use spawn which is an EventEmmiter object. Then you can listen to stdout/stderr events (spawn.stdout.on('data',callback..)) as they happen.

    From NodeJS documentation:

    var spawn = require('child_process').spawn,
        ls    = spawn('ls', ['-lh', '/usr']);
    
    ls.stdout.on('data', function (data) {
      console.log('stdout: ' + data.toString());
    });
    
    ls.stderr.on('data', function (data) {
      console.log('stderr: ' + data.toString());
    });
    
    ls.on('exit', function (code) {
      console.log('child process exited with code ' + code.toString());
    });
    

    exec buffers the output and usually returns it when the command has finished executing.

    0 讨论(0)
  • 2020-11-29 15:30

    Inspired by Nathanael Smith's answer and Eric Freese's comment, it could be as simple as:

    var exec = require('child_process').exec;
    exec('coffee -cw my_file.coffee').stdout.pipe(process.stdout);
    
    0 讨论(0)
  • 2020-11-29 15:37

    exec will also return a ChildProcess object that is an EventEmitter.

    var exec = require('child_process').exec;
    var coffeeProcess = exec('coffee -cw my_file.coffee');
    
    coffeeProcess.stdout.on('data', function(data) {
        console.log(data); 
    });
    

    OR pipe the child process's stdout to the main stdout.

    coffeeProcess.stdout.pipe(process.stdout);
    

    OR inherit stdio using spawn

    spawn('coffee -cw my_file.coffee', { stdio: 'inherit' });
    
    0 讨论(0)
  • 2020-11-29 15:43

    I'd just like to add that one small issue with outputting the buffer strings from a spawned process with console.log() is that it adds newlines, which can spread your spawned process output over additional lines. If you output stdout or stderr with process.stdout.write() instead of console.log(), then you'll get the console output from the spawned process 'as is'.

    I saw that solution here: Node.js: printing to console without a trailing newline?

    Hope that helps someone using the solution above (which is a great one for live output, even if it is from the documentation).

    0 讨论(0)
提交回复
热议问题