Joe*_*ite 53 child-process node.js
我正在尝试从Node.js启动一个shell命令,而不重定向该命令的输入和输出 - 就像使用shell脚本弹出命令或使用Ruby的system命令一样.如果子进程想要写入STDOUT,我希望它直接进入控制台(或重定向,如果我的Node应用程序的输出被重定向).
Node似乎没有任何直接的方法来做到这一点.看起来运行另一个进程的唯一方法是使用child_process,它总是将子进程的输入和输出重定向到管道.我可以编写代码来接受来自这些管道的数据并将其写入我的进程的STDOUT和STDERR,但是如果我这样做,API会迫使我牺牲一些灵活性.
我想要两个功能:
看起来Node想强迫我在这两个功能之间做出选择.
child_process.spawn,然后做child.stdout.on('data', function(data) { process.stdout.write(data); });同样的事情stderr,并且它会愉快地管道数据,直到奶牛回家.不幸的是,spawn不支持shell语法.child_process.exec.但是exec坚持要为我缓冲子进程的STDOUT和STDERR并最终将它们交给我,并且它限制了这些缓冲区的大小(可配置,默认为200K).我仍然可以挂钩on('data')事件,如果我想看到生成的输出,但exec仍然会将数据添加到其缓冲区.当数据量超过预定义的缓冲区大小时,exec将终止子进程.(从灵活性的角度来看child_process.execFile,这也是两个世界中最糟糕的:没有shell语法,但你仍然需要限制你期望的输出量.)
我错过了什么吗?有没有办法在Node中弹出子进程,而不是重定向其输入和输出?支持shell语法并且在预定义的输出量之后不会丢失的东西,就像在shell脚本,Ruby等中可用的那样?
And*_*rov 42
您可以通过spawn参数继承stdin/out/error流,因此您无需手动管道它们:
var spawn = require('child_process').spawn;
spawn('ls', [], { stdio: 'inherit' });
Run Code Online (Sandbox Code Playgroud)
使用shell进行shell语法 - 对于bash它的-c参数从字符串中读取脚本:
var spawn = require('child_process').spawn;
var shellSyntaxCommand = 'ls -l | grep test | wc -c';
spawn('sh', ['-c', shellSyntaxCommand], { stdio: 'inherit' });
Run Code Online (Sandbox Code Playgroud)
总结一下:
var spawn = require('child_process').spawn;
function shspawn(command) {
spawn('sh', ['-c', command], { stdio: 'inherit' });
}
shspawn('ls -l | grep test | wc -c');
Run Code Online (Sandbox Code Playgroud)
您可以替换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 ());
});
Run Code Online (Sandbox Code Playgroud)
魔术是正义的{shell: true}。
我没有使用过它,但我见过这个库:https://github.com/polotek/procstreams
如果你这样做的话。自动.out()通过管道连接到进程的标准输入/输出。
var $p = require('procstreams');
$p('cat lines.txt').pipe('wc -l').out();
Run Code Online (Sandbox Code Playgroud)
if 不支持 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
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
31635 次 |
| 最近记录: |