azBrian
azBrian

Reputation: 668

Using Node.js, how can I execute mutiple commands on a child process and get the response after each command?

I'm trying to use Node.js to get information about multiple SVG files via Inkscape.

I can run something like Inkscape file.svg --select=id -W & Inkscape file2.svg --select=id -W (to get the width of two files) but it uses two instances of Inkscape to do it which is slow.

Using the --shell option of Inkscape you can run multiple commands very quickly because Inkscape initializes only once. http://tavmjong.free.fr/INKSCAPE/MANUAL/html/CommandLine.html

However, I cannot figure out how to use the Inkscape shell with Node.js because all the child_process types seem to expect response AND exit after every command otherwise it just hangs until timeout or the program is closed.

I would love for some sort of functionality like the below.

var Inkscape = require('hypothetical_module').execSync('Inkscape --shell');
var file1width = Inkscape.execSync('file.svg -W');
var file2width = Inkscape.execSync('file2.svg -W');
if(file1width > 200){ Inkscape.execSync('file.svg --export-pdf=file.pdf'); }
if(file2width > 200){ Inkscape.execSync('file2.svg --export-pdf=file2.pdf'); }
Inkscape.exec('quit');

Here is a sample of running Inkscape from cmd with a test file called "acid.svg"

C:\Program Files (x86)\Inkscape>Inkscape --shell
Inkscape 0.91 r13725 interactive shell mode. Type 'quit' to quit.
>acid.svg -W
106>acid.svg -H
93.35223>quit

Upvotes: 1

Views: 1034

Answers (1)

glenn jackman
glenn jackman

Reputation: 246744

You'll have to stop using the synchronous commands. Here's a toy example:

I am calling this program, repl.sh

#!/bin/sh
while :; do
    printf "> "
    read -r cmd
    case "$cmd" in
        quit) echo bye; exit ;;
        *) echo "you wrote: $cmd" ;;
    esac
done

And, node.js code:

#!/usr/local/bin/node

var spawn = require('child_process').spawn,
    prog = './repl.sh',
    cmdno = 0,
    cmds = ['foo -bar -baz', 'one -2 -3', 'quit'];


var repl = spawn(prog, ['--prog', '--options']);

repl.stdout.on('data', function (data) {
    console.log('repl output: ' + data);
    if (cmdno < cmds.length) {
        console.log('sending: ' + cmds[cmdno]);
        repl.stdin.write(cmds[cmdno] + "\n");
        cmdno++
    }
});

repl.on('close', function (code) {
    console.log('repl is closed: ' + code);
});

repl.on('error', function (code) {
    console.log('repl error: ' + code);
});

This outputs:

$ node repl.driver.js
repl output: > 
sending: foo -bar -baz
repl output: you wrote: foo -bar -baz
> 
sending: one -2 -3
repl output: you wrote: one -2 -3
> 
sending: quit
repl output: bye

repl is closed: 0

Upvotes: 1

Related Questions