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 在我的 TypeScript 模块中返回一个 Promise?
如何将字符串解析为 child_process.spawn 的适当参数?
如何模拟 Node.js child_process spawn 函数?
nodejs child_process.spawnSync 或 child_process.spawn 包裹在 yieldable 生成器中,它返回输出