child_process spawn() 中的通配符?

Posted

技术标签:

【中文标题】child_process spawn() 中的通配符?【英文标题】:Wildcards in child_process spawn()? 【发布时间】:2012-07-27 20:55:41 【问题描述】:

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

我试过了

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

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

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

谢谢

托本

【问题讨论】:

【参考方案1】:

这是最简单的解决方案:

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

正如@JamieBirch 在他的评论中所建议的那样,关键是告诉spawn() 使用shell( shell: true ,see the docs),所以通配符被正确解析。

【讨论】:

【参考方案2】:

* 正在被 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 核心代码中,我们可以观察到一种通过 spawn 在 shell 中调用任意命令的方法,同时保留完整的 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]);

【讨论】:

【参考方案3】:

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

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

【讨论】:

或者:传入shell 选项,例如:spawn("doSomething", ["./myfiles/*.csv"], shell: true ) @JamieBirch 不错!

以上是关于child_process spawn() 中的通配符?的主要内容,如果未能解决你的问题,请参考以下文章

节点 child_process.spawn 多个命令

如何让 child_process.spawn 在我的 TypeScript 模块中返回一个 Promise?

如何将字符串解析为 child_process.spawn 的适当参数?

如何模拟 Node.js child_process spawn 函数?

nodejs child_process.spawnSync 或 child_process.spawn 包裹在 yieldable 生成器中,它返回输出

如何使用 nodejs child_process.spawn 捕获 ENOENT?