我正在尝试从Node.js启动一个shell命令,没有重定向该命令的输入和输出 - 就像使用shell脚本弹出命令一样,或者使用Ruby的{{ 1}}命令。如果子进程想要写入STDOUT,我希望它直接进入控制台(或重定向,如果我的Node应用程序的输出被重定向)。
Node似乎没有任何直接的方法来执行此操作。看起来运行另一个进程的唯一方法是使用system
,始终将子进程的输入和输出重定向到管道。我可以编写代码来接受来自这些管道的数据并将其写入我的进程的STDOUT和STDERR,但是如果我这样做,API会迫使我牺牲一些灵活性。
我想要两个功能:
看起来Node想强迫我在这两个功能之间做出选择。
child_process.spawn
,然后对child_process
执行child.stdout.on('data', function(data) { process.stdout.write(data); });
和同样的事情,并且它会愉快地管理数据直到奶牛来家。不幸的是,stderr
不支持shell语法。child_process.exec
。但是spawn
坚持为我缓冲子进程的STDOUT和STDERR并在最后将它们全部交给我,并且它限制了这些缓冲区的大小(可配置,默认为200K)。我仍然可以挂钩exec
事件,如果我想看到生成的输出,但on('data')
仍会将数据添加到其缓冲区。当数据量超过预定义的缓冲区大小时,exec
将终止子进程。(还有child_process.execFile
,从灵活性的角度来看,这两个世界的最差:没有shell语法,但你仍然需要限制你期望的输出量。)< / p>
我错过了什么吗? 有没有办法在Node中弹出子进程,而不重定向其输入和输出?支持shell语法的东西,并且不会在预定义的输出量,就像在shell脚本,Ruby等中可用的那样?
答案 0 :(得分:41)
您可以通过spawn
参数继承stdin / out / error流,这样您就不需要手动管道它们了:
var spawn = require('child_process').spawn;
spawn('ls', [], { stdio: 'inherit' });
使用shell进行shell语法 - 对于bash它的-c
参数从字符串中读取脚本:
var spawn = require('child_process').spawn;
var shellSyntaxCommand = 'ls -l | grep test | wc -c';
spawn('sh', ['-c', shellSyntaxCommand], { stdio: 'inherit' });
总结:
var spawn = require('child_process').spawn;
function shspawn(command) {
spawn('sh', ['-c', command], { stdio: 'inherit' });
}
shspawn('ls -l | grep test | wc -c');
答案 1 :(得分:5)
您可以将exec
替换为spawn
,并将shell语法简单地用于:
const {spawn} = require ('child_process');
const cmd = 'ls -l | grep test | wc -c';
const p = spawn (cmd, [], {shell: true});
p.stdout.on ('data', (data) => {
console.log (data.toString ());
});
魔术只是{shell: true}
。
答案 2 :(得分:4)
我没有使用它,但我看过这个库:https://github.com/polotek/procstreams
你会这样做。 .out()
自动管道进程的stdin / out。
var $p = require('procstreams');
$p('cat lines.txt').pipe('wc -l').out();
如果不支持shell语法,但我认为这非常简单。
var command_str = "cat lines.txt | wc -l";
var cmds = command_str.split(/\s?\|\s?/);
var cmd = $p(cmds.shift());
while(cmds.length) cmd = cmd.pipe(cmds.shift());
cmd
.out()
.on('exit', function() {
// Do whatever
});
答案 3 :(得分:0)
child_process模块的node docs中有一个例子:
分离长时间运行的进程并将其输出重定向到文件的示例:
var fs = require('fs'),
spawn = require('child_process').spawn,
out = fs.openSync('./out.log', 'a'),
err = fs.openSync('./out.log', 'a');
var child = spawn('prg', [], {
detached: true,
stdio: [ 'ignore', out, err ]
});
child.unref();