问题 child_process spawn()中的通配符?


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

我试过这个

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

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

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

谢谢

托本


2840
2017-07-30 07:44


起源



答案:


* 由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中自己扩展通配符文件模式 节点水珠 在创建子进程之前?

更新

在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]);
}

9
2018-02-11 11:20





你用的是什么操作系统?在Unix系列操作系统(例如Linux,MacOS)中,程序希望shell进程扩展通配符文件名参数并传递扩展名 argv[]。在Windows操作系统中,程序通常希望必须自己扩展通配符(尽管只有它们是Windows本机程序;移植的Unix系列程序最多可能尝试通过兼容层运行参数)。

你的语法看起来像是Unix系列的。如果是这样,那么当你打电话 spawn() 你绕过shell扩展,你的子进程将在字面上处理参数中的点和星号。尝试使用 sh child_process 代替 child_process 看看你是否得到了更好的结果。


1
2017-07-30 10:02



另外:传球 shell 选项,例如: spawn("doSomething", ["./myfiles/*.csv"], { shell: true }) - Jamie Birch
@JamieBirch好赶上那里! - Karl Morrison


答案:


* 由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中自己扩展通配符文件模式 节点水珠 在创建子进程之前?

更新

在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]);
}

9
2018-02-11 11:20





你用的是什么操作系统?在Unix系列操作系统(例如Linux,MacOS)中,程序希望shell进程扩展通配符文件名参数并传递扩展名 argv[]。在Windows操作系统中,程序通常希望必须自己扩展通配符(尽管只有它们是Windows本机程序;移植的Unix系列程序最多可能尝试通过兼容层运行参数)。

你的语法看起来像是Unix系列的。如果是这样,那么当你打电话 spawn() 你绕过shell扩展,你的子进程将在字面上处理参数中的点和星号。尝试使用 sh child_process 代替 child_process 看看你是否得到了更好的结果。


1
2017-07-30 10:02



另外:传球 shell 选项,例如: spawn("doSomething", ["./myfiles/*.csv"], { shell: true }) - Jamie Birch
@JamieBirch好赶上那里! - Karl Morrison