Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wildcards in child_process spawn()?

I want to execute a command like "doSomething ./myfiles/*.csv" with spawn in node.js. I want to use spawn instead of exec, because it is some kind of watch process and I need the stdout output.

I tried this

var spawn = require('child_process').spawn; 
spawn("doSomething", ["./myfiles/*.csv"]);

But then the wildcard *.csv will not interpreted.

Is it not possible to use wildcards when using spawn()? Are there other possibilities to solve this problem?

Thanks

Torben

like image 264
Torben Avatar asked Jul 30 '12 07:07

Torben


People also ask

What is Child_process spawn?

child_process.exec() : spawns a shell and runs a command within that shell, passing the stdout and stderr to a callback function when complete.

How do you spawn in Javascript?

The spawn function launches a command in a new process and we can use it to pass that command any arguments. For example, here's code to spawn a new process that will execute the pwd command. const { spawn } = require('child_process'); const child = spawn('pwd');

How do I run an exec in node JS?

The exec() function in Node. js creates a new shell process and executes a command in that shell. The output of the command is kept in a buffer in memory, which you can accept via a callback function passed into exec() .


2 Answers

The * is being expanded by the shell, and for child_process.spawn the arguments are coming through as strings so will never get properly expanded. It's a limitation of spawn. You could try child_process.exec instead, it will allow the shell to expand any wildcards properly:

var exec = require("child_process").exec;

var child = exec("doSomething ./myfiles/*.csv",function (err,stdout,stderr) {
    // Handle result
});

If you really need to use spawn for some reason perhaps you could consider expanding the wildcard file pattern yourself in Node with a lib like node-glob before creating the child process?

Update

In the Joyent Node core code we can observe an approach for invoking an arbitrary command in a shell via spawn while retaining full shell wildcard expansion:

https://github.com/joyent/node/blob/937e2e351b2450cf1e9c4d8b3e1a4e2a2def58bb/lib/child_process.js#L589

And here's some pseudo code:

var child;
var cmd = "doSomething ./myfiles/*.csv";

if ('win32' === process.platform) {
    child = spawn('cmd.exe', ['/s', '/c', '"' + cmd + '"'],{windowsVerbatimArguments:true} );
} else {
    child = spawn('/bin/sh', ['-c', cmd]);
}
like image 191
Jed Richards Avatar answered Oct 17 '22 21:10

Jed Richards


Here's the simplest solution:

spawn("doSomething", ["./myfiles/*.csv"], { shell: true });

As @JamieBirch suggested in his comment, the key is telling spawn() to use the shell ({ shell: true }, see the docs), so the wildcard is properly resolved.

like image 33
Lucio Paiva Avatar answered Oct 17 '22 19:10

Lucio Paiva