从Node.js运行Shell命令而不缓冲输出 [英] Running a shell command from Node.js without buffering output

查看:64
本文介绍了从Node.js运行Shell命令而不缓冲输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从Node.js启动shell命令,重定向该命令的输入和输出-就像使用shell脚本或使用Ruby的系统命令.如果子进程想要写入STDOUT,则我希望它直接进入控制台(或重定向,如果Node应用程序的输出已重定向).

I'm trying to launch a shell command from Node.js, without redirecting that command's input and output -- just like shelling out to a command using a shell script, or using Ruby's system command. If the child process wants to write to STDOUT, I want that to go straight to the console (or get redirected, if my Node app's output was redirected).

Node似乎没有任何直接的方法来执行此操作.看来,运行另一个进程的唯一方法是使用 child_process ,它总是将子进程的输入和输出重定向到管道.我可以编写代码以接受来自那些管道的数据,然后将其写入进程的STDOUT和STDERR,但是如果这样做,API会迫使我牺牲一些灵活性.

Node doesn't seem to have any straightforward way to do this. It looks like the only way to run another process is with child_process, which always redirects the child process's input and output to pipes. I can write code to accept data from those pipes and write it to my process's STDOUT and STDERR, but if I do that, the APIs force me to sacrifice some flexibility.

我想要两个功能:

  • Shell语法.我希望能够在命令之间传递输出,或运行Windows批处理文件.
  • 无限的输出.如果我要使用编译器,并且希望生成兆字节的编译器警告,则希望它们全部在屏幕上滚动(直到用户厌倦了该警告并按Ctrl + C组合键.)

Node似乎要强迫我在这两个功能之间进行选择.

It looks like Node wants to force me choose between those two features.

  • 如果我想要无限量的输出,可以使用 child_process.spawn 然后执行 child.stdout.on('data',function(data){process.stdout.write(data);}); stderr ,它会愉快地传递数据,直到奶牛回家.不幸的是, spawn 不支持shell语法.
  • 如果我需要shell语法,则可以使用 child_process.exec .但是 exec 坚持为我缓冲子进程的STDOUT和STDERR并最终将它们全部提供给我,并且它限制了这些缓冲区的大小(可配置,默认为200K).如果我想查看生成的输出,我仍然可以挂钩 on('data')事件,但是 exec 仍会将数据也添加到其缓冲区中.当数据量超过预定义的缓冲区大小时, exec 将终止子进程.
  • If I want an unlimited amount of output, I can use child_process.spawn and then do child.stdout.on('data', function(data) { process.stdout.write(data); }); and the same thing for stderr, and it'll happily pipe data until the cows come home. Unfortunately, spawn doesn't support shell syntax.
  • If I want shell syntax, I can use child_process.exec. But exec insists on buffering the child process's STDOUT and STDERR for me and giving them to me all at the end, and it limits the size of those buffers (configurable, 200K by default). I can still hook the on('data') events, if I want to see the output as it's generated, but exec will still add the data to its buffers too. When the amount of data exceeds the predefined buffer size, exec will terminate the child process.

(还有 child_process.execFile ,这是最糟糕的从灵活性的角度来看这两个世界:没有shell语法,但是您仍然必须限制期望的输出量.)

(There's also child_process.execFile, which is the worst of both worlds from a flexibility standpoint: no shell syntax, but you still have to cap the amount of output you expect.)

我错过了什么吗?有什么方法可以只封装到Node中的子进程,而重定向其输入和输出?某些支持shell语法并且在出现预定义的输出量,就像Shell脚本,Ruby等中提供的一样?

Am I missing something? Is there any way to just shell out to a child process in Node, and not redirect its input and output? Something that supports shell syntax and doesn't crap out after a predefined amount of output, just like is available in shell scripts, Ruby, etc.?

推荐答案

您可以通过 spawn 参数继承stdin/out/error流,因此您无需手动传递它们:

You can inherit stdin/out/error streams via spawn argument so you don't need to pipe them manually:

var spawn = require('child_process').spawn;
spawn('ls', [], { stdio: 'inherit' });

使用shell进行shell语法-对于bash,使用 -c 参数从字符串中读取脚本:

Use shell for shell syntax - for bash it's -c parameter to read script from string:

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');

这篇关于从Node.js运行Shell命令而不缓冲输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆