child_process spawn()中的通配符?

Tor*_*ben 13 exec spawn node.js

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

我试过这个

var spawn = require('child_process').spawn; 
spawn("doSomething", ["./myfiles/*.csv"]);
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢

托本

Jed*_*rds 8

*是由外壳扩展,并为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
});
Run Code Online (Sandbox Code Playgroud)

如果您真的需要spawn出于某种原因使用,或许您可以考虑在创建子进程之前使用类似node-glob的lib在Node中自己扩展通配符文件模式?

更新

在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]);
}
Run Code Online (Sandbox Code Playgroud)


Luc*_*iva 5

这是最简单的解决方案:

spawn("doSomething", ["./myfiles/*.csv"], { shell: true });
Run Code Online (Sandbox Code Playgroud)

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


ebo*_*man 0

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

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

  • 或者:传入`shell`选项,例如:`spawn("doSomething", ["./myfiles/*.csv"], { shell: true })` (3认同)