17

我想在 node.js 中执行类似“doSomething ./myfiles/*.csv”的命令。我想使用 spawn 而不是 exec,因为它是某种监视进程,我需要 stdout 输出。

我试过这个

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

但是通配符 *.csv 将不会被解释。

使用 spawn() 时不能使用通配符吗?还有其他可能解决这个问题吗?

谢谢

托本

4

3 回答 3

10

*正在由 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 中使用类似node-glob的库自己扩展通配符文件模式?

更新

在 Joyent Node 核心代码中,我们可以观察到一种在 shell 中调用任意命令的方法,spawn同时保留完整的 shell 通配符扩展:

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

这是一些伪代码:

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]);
}
于 2014-02-11T11:20:18.543 回答
6

这是最简单的解决方案:

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

正如@JamieBirch 在他的评论中所建议的那样,关键是告诉spawn()使用外壳({ shell: true }请参阅文档),因此通配符已正确解析。

于 2019-08-12T19:35:43.400 回答
0

您使用的是什么操作系统?在 Unix 系列操作系统(例如 Linux、MacOS)中,程序期望 shell 进程扩展通配符文件名参数并将扩展传递到argv[]. 在 Windows 操作系统中,程序通常需要自己扩展通配符(尽管只有当它们是 Windows 原生程序时;移植的 Unix 系列程序最多可能会尝试通过兼容层运行参数)。

您的语法看起来像是适用于 Unix 系列系统。如果是这样,那么当您调用时,spawn()您将绕过外壳扩展,并且您的子进程将逐字处理参数中的点和星号。尝试使用sh child_process代替,child_process看看你是否能得到更好的结果。

于 2012-07-30T10:02:26.013 回答