How do you pipe a long string to /dev/stdin via child_process.spawn() in Node.js?

后端 未结 4 1519
失恋的感觉
失恋的感觉 2021-02-07 07:39

I\'m trying to execute Inkscape by passing data via stdin. Inkscape only supports this via /dev/stdin. Basically, I\'m trying to do something like this

4条回答
  •  無奈伤痛
    2021-02-07 08:29

    Alright, I don't have Inkscape, but this appears to solve the Node.js side of things. I'm using wc as a stand in Inkscape; the -c option simply outputs the number of bytes in a given file (in this case /dev/stdin).

    var child_process = require('child_process');
    
    /**
     * Create the child process, with output piped to the script's stdout
     */
    var wc = child_process.spawn('wc', ['-c', '/dev/stdin']);
    wc.stdout.pipe(process.stdout);
    
    /**
     * Write some data to stdin, and then use stream.end() to signal that we're
     * done writing data.
     */
    wc.stdin.write('test');
    wc.stdin.end();
    

    The trick seems to be signaling that you're done writing to the stream. Depending on how large your SVG is, you may need to pay attention to backpressure from Inkscape by handling the 'drain' event.


    As for passing a stream into the child_process.spawn call, you instead need to use the 'pipe' option, and then pipe a readable stream into child.stdin, as shown below. I know this works in Node v0.10.26, but not sure about before that.

    var stream = require('stream');
    var child_process = require('child_process');
    
    /**
     * Create the child process, with output piped to the script's stdout
     */
    var wc = child_process.spawn('wc', ['-c', '/dev/stdin'], {stdin: 'pipe'});
    wc.stdout.pipe(process.stdout);
    
    /**
     * Build a readable stream with some data pushed into it.
     */
    var readable = new stream.Readable();
    readable._read = function noop() {}; // See note below
    readable.push('test me!');
    readable.push(null);
    
    /**
     * Pipe our readable stream into wc's standard input.
     */
    readable.pipe(wc.stdin);
    

    Obviously, this method is a bit more complicated, and you should use the method above unless you have good reason to (you're effectively implementing your own readable string).

    Note: The readable._push function must be implemented according to the docs, but it doesn't necessarily have to do anything.

提交回复
热议问题