nmrugg nmrugg - 2 months ago 21
Node.js Question

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

I'm trying to execute Inkscape by passing data via

. Inkscape only supports this via
. Basically, I'm trying to do something like this:

echo "<sgv>...</svg>" | inkscape -z -f /dev/stdin -A /dev/stdout

I don't want to have to write the SVG to disk.

I tried just using
, but it doesn't work (maybe because of

var cmd = spawn("inkscape", ["-z", "-f", "/dev/stdin", "-A", "/dev/stdout"], {encoding: "buffer", stdio: ["pipe", stdoutPipe, "pipe"]});


This does work, but I have to write the SVG to disk:

var cmd = spawn("inkscape", ["-z", "-f", "/dev/stdin", "-A", "/dev/stdout"], {encoding: "buffer", stdio: [fs.openSync('file.svg', "a"), stdoutPipe, "pipe"]});

I tried passing a stream to
, but I just keep getting
TypeError: Incorrect value for stdio stream: [object Object]

Any ideas?


The examples use Inkscape, but my question applies to any arbitrary program using

By the way, this would work for me:

var exec = require('child_process').exec;
exec("echo \"<svg>...</svg>\" | inkscape -z -f /dev/stdin -A /dev/stdout | cat", function (error, stdout, stderr) {});

Except, my SVG is too long, so it throws an error:
Error: spawn Unknown system errno 7


So, I figured out a work around. This seems like a bit of a hack, but it works just fine.

First, I made this one line shell script:

cat | inkscape -z -f /dev/stdin -A /dev/stdout | cat

Then, I simply spawn that file and write to the stdin like this:

cmd = spawn("shell_script");


I really think this should work without the shell script, but it won't (for me at least). This may be a Node.js bug.