我想在node.js中使用spawn执行类似“doSomething ./myfiles/*.csv”的命令。我想使用spawn而不是exec,因为它是某种监视进程,我需要stdout输出。
我试过这个
var spawn = require('child_process').spawn;
spawn("doSomething", ["./myfiles/*.csv"]);
但是通配符* .csv不会被解释。
使用spawn()时是否无法使用通配符?还有其他可能解决这个问题吗?
谢谢
托本
答案 0 :(得分:9)
shell正在扩展*
,对于child_process.spawn
,参数作为字符串传递,因此永远不会被正确扩展。这是spawn
的限制。您可以尝试child_process.exec
,它将允许shell正确扩展任何通配符:
var exec = require("child_process").exec;
var child = exec("doSomething ./myfiles/*.csv",function (err,stdout,stderr) {
// Handle result
});
如果出于某种原因确实需要使用spawn
,或许您可以考虑在创建子进程之前使用像node-glob这样的库在Node中扩展通配符文件模式吗?
在Joyent Node核心代码中,我们可以观察到一种通过spawn
在shell中调用任意命令同时保留完整的shell通配符扩展的方法:
这里有一些伪代码:
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]);
}
答案 1 :(得分:1)
您使用的操作系统是什么?在Unix系列操作系统(例如Linux,MacOS)中,程序希望shell进程扩展通配符文件名参数并在argv[]
中传递扩展。在Windows操作系统中,程序通常希望必须自己扩展通配符(尽管只有它们是Windows本机程序;移植的Unix系列程序最多可能尝试通过兼容层运行参数)。
你的语法看起来像是Unix系列的。如果是这样,那么当你调用spawn()
时,你绕过shell扩展,你的子进程就会在字面上处理参数中的点和星号。尝试使用sh child_process
代替child_process
,看看您是否获得了更好的结果。
答案 2 :(得分:0)
这是最简单的解决方案:
spawn("doSomething", ["./myfiles/*.csv"], { shell: true });
正如@JamieBirch在评论中建议的那样,关键是告诉spawn()
使用shell({ shell: true }
,see the docs),以便正确解析通配符。