jjzjj

javascript - Node.js:捕获 `child_process.spawn` 的 STDOUT

coder 2024-07-23 原文

我需要在生成的子进程的自定义 输出中捕获。

child_process.spawn(command[, args][, options])

例如,

var s = fs.createWriteStream('/tmp/test.txt');
child_process.spawn('ifconfig', [], {stdio: [null, s, null]})

现在如何实时读取 /tmp/test.txt

看起来 child_process.spawn 没有使用 stream.Writable.prototype.write 也没有使用 stream.Writable.prototype._write执行。

例如,

s.write = function() { console.log("this will never get printed"); };

还有,

s.__proto__._write = function() { console.log("this will never get printed"); };

看起来它使用文件描述符在幕后child_process.spawn 写入文件。

这样做是行不通的:

var s2 = fs.createReadStream('/tmp/test.txt');
s2.on("data", function() { console.log("this will never get printed either"); });

那么,如何获取子进程的 STDOUT 内容呢?

我想要实现的是将子进程的 STDOUT 流式传输到套接字。如果我将套接字作为 stdio 参数直接提供给 child_process.spawn,它会在完成时关闭套接字,但我想让它保持打开状态。

更新:

解决方案是使用默认的 {stdio: ['pipe', 'pipe', 'pipe']} 选项并监听创建的 .stdout子进程。

var cmd = child_process.spaw('ifconfig');
cmd.stdout.on("data", (data) => { ... });

现在,提高赌注,一个更具挑战性的问题:

-- 如何读取子进程的 STDOUT 并仍然保留颜色?

例如,如果您像这样将 STDOUT 发送到 process.stdout:

child_process.spawn('ifconfig', [], {stdio: [null, process.stdout, null]});

它将保留颜色并将彩色输出打印到控制台,因为 .isTTY 属性在 process.stdout 上设置为 true .

process.stdout.isTTY // true

现在,如果您使用默认的 {stdio: ['pipe', 'pipe', 'pipe']},您将读取的数据将被去除控制台颜色。你如何获得颜色?

一种方法是使用 fs.createWriteStream 创建您自己的自定义流,因为 child_process.spawn 要求您的流具有文件描述符。

然后将该流的 .isTTY 设置为 true,以保留颜色。

最后,您需要捕获 child_process.spawn 写入该流的数据,但由于 child_process.spawn 不使用 .prototype.write 或流的 .prototype._write,您需要以其他一些hacky 方式捕获其内容。

这可能就是为什么 child_process.spawn 要求您的流具有文件描述符的原因,因为它绕过了 .prototype.write 调用并直接写入文件 -引擎盖

有什么想法可以实现吗?

最佳答案

你可以在不使用临时文件的情况下做到这一点:

var process = child_process.spawn(command[, args][, options]);
process.stdout.on('data', function (chunk) {
    console.log(chunk);
});

关于javascript - Node.js:捕获 `child_process.spawn` 的 STDOUT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30616749/

有关javascript - Node.js:捕获 `child_process.spawn` 的 STDOUT的更多相关文章

  1. ruby - 将 spawn() 的标准输出/标准错误重定向到 Ruby 中的字符串 - 2

    我想使用spawn(针对多个并发子进程)在Ruby中执行一个外部进程,并将标准输出或标准错误收集到一个字符串中,其方式类似于使用Python的子进程Popen.communicate()可以完成的操作。我尝试将:out/:err重定向到一个新的StringIO对象,但这会生成一个ArgumentError,并且临时重新定义$stdxxx会混淆子进程的输出。 最佳答案 如果你不喜欢popen,这是我的方法:r,w=IO.pipepid=Process.spawn(command,:out=>w,:err=>[:child,:out])

  2. ruby - 如何让Ruby捕获线程中的语法错误 - 2

    我正在尝试使用ruby​​编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?

  3. ruby - Ruby 是否使用 $stdout 来写入 puts 和 return 的输出? - 2

    我想知道Ruby用来在命令行打印这些东西的输出流:irb(main):001:0>a="test"=>"test"irb(main):002:0>putsatest=>nilirb(main):003:0>a=>"test"$stdout是否用于irb(main):002:0>和irb(main):003:0>?而且,在这两次调用之间,$stdout的值是否有任何变化?另外,有人能告诉我打印/写入这些内容的Ruby源代码吗? 最佳答案 是的。而且很容易向自己测试/证明。在命令行试试这个:ruby-e'puts"foo"'>test.

  4. ruby-on-rails - 无法在 Rails 助手中捕获 block 的输出 - 2

    我在使用自定义RailsFormBuilder时遇到了问题,从昨天晚上开始我就发疯了。基本上我想对我的构建器方法之一有一个可选block,以便我可以在我的主要content_tag中显示其他内容。:defform_field(method,&block)content_tag(:div,class:'field')doconcatlabel(method,"Label#{method}")concattext_field(method)capture(&block)ifblock_given?endend当我在我的一个Slim模板中调用该方法时,如下所示:=f.form_field:e

  5. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

  6. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  7. ruby - 在 ruby​​ 中生成一个进程,捕获 stdout,stderr,获取退出状态 - 2

    我想从ruby​​rake脚本运行一个可执行文件,比如foo.exe我希望将foo.exe的STDOUT和STDERR输出直接写入我正在运行rake任务的控制台.当进程完成时,我想将退出代码捕获到一个变量中。我如何实现这一目标?我一直在玩backticks、process.spawn、system但我无法获得我想要的所有行为,只有部分更新:我在Windows上,在标准命令提示符下,而不是cygwin 最佳答案 system获取您想要的STDOUT行为。它还返回true作为零退出代码,这可能很有用。$?填充了有关最后一次system调

  8. Ruby:写入 stdin 并从 stdout 读取? - 2

    我正在编写一个ruby​​程序,它应该执行另一个程序,通过stdin向它传递值,从它的stdout读取响应,然后打印响应。这是我目前所拥有的。#!/usr/bin/envrubyrequire'open3'stdin,stdout,stderr=Open3.popen3('./MyProgram')stdin.puts"helloworld!"output=stdout.readerrors=stderr.readstdin.closestdout.closestderr.closeputs"Output:"puts"-------"putsoutputputs"\nErrors:"p

  9. ruby - 捕获 Ruby Logger 输出以进行测试 - 2

    我有一个像这样的ruby​​类:require'logger'classTdefdo_somethinglog=Logger.new(STDERR)log.info("Hereisaninfomessage")endend测试脚本行如下:#!/usr/bin/envrubygem"minitest"require'minitest/autorun'require_relative't'classTestMailProcessorClasses当我运行这个测试时,out和err都是空字符串。我看到消息打印在stderr上(在终端上)。有没有办法让Logger和capture_io一起玩得

  10. ruby - Capistrano 中的执行、测试和捕获命令有什么区别? - 2

    关于SSHkit-Github它说:Allbackendssupporttheexecute(*args),test(*args)&capture(*args)来自SSHkit-Rubydoc,我明白execute实际上是test的别名?test之间有什么区别?,execute,capture在Capistrano/SSHKit中我应该什么时候使用? 最佳答案 执行只是执行命令。使用非0退出引发错误。测试方法的行为与execute完全相同,但是它返回bool值(true如果命令以0退出,而false否则)。它通常用于控制任务中的流程

随机推荐