简体   繁体   English

child_process spawn()中的通配符?

[英]Wildcards in child_process spawn()?

I want to execute a command like "doSomething ./myfiles/*.csv" with spawn in node.js. 我想在node.js中执行类似“ doSomething ./myfiles/*.csv”的命令。 I want to use spawn instead of exec, because it is some kind of watch process and I need the stdout output. 我想使用spawn而不是exec,因为这是某种监视过程,因此我需要stdout输出。

I tried this 我试过了

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

But then the wildcard *.csv will not interpreted. 但是通配符* .csv不会被解释。

Is it not possible to use wildcards when using spawn()? 使用spawn()时不能使用通配符吗? Are there other possibilities to solve this problem? 还有其他解决此问题的可能性吗?

Thanks 谢谢

Torben 托本

The * is being expanded by the shell, and for child_process.spawn the arguments are coming through as strings so will never get properly expanded. *正在由外壳扩展,对于child_process.spawn ,参数作为字符串传递,因此永远不会正确扩展。 It's a limitation of spawn . 这是spawn的限制。 You could try child_process.exec instead, it will allow the shell to expand any wildcards properly: 您可以尝试使用child_process.exec ,它将允许外壳程序适当地扩展任何通配符:

var exec = require("child_process").exec;

var child = exec("doSomething ./myfiles/*.csv",function (err,stdout,stderr) {
    // Handle result
});

If you really need to use spawn for some reason perhaps you could consider expanding the wildcard file pattern yourself in Node with a lib like node-glob before creating the child process? 如果由于某些原因确实需要使用spawn ,也许可以考虑在创建子进程之前使用像node-glob这样的库在Node中自己扩展通配符文件模式?

Update 更新资料

In the Joyent Node core code we can observe an approach for invoking an arbitrary command in a shell via spawn while retaining full shell wildcard expansion: 在Joyent Node核心代码中,我们可以观察到一种通过spawn在shell中调用任意命令,同时保留完整的shell通配符扩展的方法:

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

And here's some pseudo code: 这是一些伪代码:

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

What OS are you using? 您正在使用什么操作系统? In Unix-family OSs (eg Linux, MacOS), programs expect the shell process to expand wildcard filename arguments and pass the expansion in argv[] . 在Unix系列操作系统(例如Linux,MacOS)中,程序期望shell进程扩展通配符文件名参数,并将扩展传递给argv[] In Windows OSs, programs usually expect to have to expand wildcards themselves (though only if they're Windows-native programs; ported Unix-family programs may at most try to run the arguments through a compatibility layer). 在Windows操作系统中,程序通常期望自己必须扩展通配符(尽管仅当它们是Windows本地程序时;移植的Unix系列程序最多只能尝试通过兼容性层运行参数)。

Your syntax looks like it's for a Unix-family system. 您的语法看起来像是针对Unix系列系统的。 If so, then when you call spawn() you're bypassing shell expansion, and your child process is going to treat dots and asterisks in arguments literally. 如果是这样,那么当您调用spawn()您将绕过Shell扩展,您的子进程将按字面意义处理参数中的点和星号。 Try using sh child_process in place of child_process and see if you get better results. 尝试使用sh child_process代替child_process ,看看是否获得更好的结果。

Here's the simplest solution: 这是最简单的解决方案:

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

As @JamieBirch suggested in his comment, the key is telling spawn() to use the shell ( { shell: true } , see the docs ), so the wildcard is properly resolved. 正如@JamieBirch在他的评论中建议的那样,关键是告诉spawn()使用shell( { shell: true }请参阅docs ),因此可以正确解析通配符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM