如何在 ruby​​19 中替换 STDIN、STDOUT、STDERR

发布于 2025-01-06 03:49:41 字数 424 浏览 1 评论 0原文

在 ruby​​18 中,我有时会执行以下操作来获得完全控制的子进程:

stdin, @stdin= IO.pipe
@stdout, stdout= IO.pipe
@stderr, stderr= IO.pipe
@pid= fork do
    @stdin.close
    STDIN.close
    stdin.dup
    @stdout.close
    STDOUT.close
    stdout.dup
    @stderr.close
    STDERR.close
    stderr.dup
    exec(...)
end

这在 ruby​​19 中不起作用。 STDIN、STDOUT、STDERR 的 close 方法不会关闭 ruby​​19 中的底层文件描述符。我该如何在 ruby​​19 中执行此操作?

In ruby18 I sometimes did the following to get a subprocess with full control:

stdin, @stdin= IO.pipe
@stdout, stdout= IO.pipe
@stderr, stderr= IO.pipe
@pid= fork do
    @stdin.close
    STDIN.close
    stdin.dup
    @stdout.close
    STDOUT.close
    stdout.dup
    @stderr.close
    STDERR.close
    stderr.dup
    exec(...)
end

This does not work in ruby19. The close method for STDIN, STDOUT, STDERR does not close the underlying filedescriptor in ruby19. How do I do this in ruby19.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陈甜 2025-01-13 03:49:41

查看 Process.spawnOpen3childprocess gem。

我无法确切地告诉您要在那里做什么,但您可以通过多种方式控制子进程的 IO。

使用 Unix 管道:使用

readme, writeme = IO.pipe
pid = fork {
    $stdout.reopen writeme
    readme.close
    exec(...)
}

Process.spawn 处理 IO:

pid = spawn(command, :err=>:out)

或者将进程包装在 POpen3 中:

require 'open3'
include Open3
popen3(RUBY, '-r', THIS_FILE, '-e', 'hello("Open3", true)') do
  |stdin, stdout, stderr|
  stdin.write("hello from parent")
  stdin.close_write
  stdout.read.split("\n").each do |line|
    puts "[parent] stdout: #{line}"
  end
  stderr.read.split("\n").each do |line|
    puts "[parent] stderr: #{line}"
  end

您也可以考虑 Jesse Storimer 的 使用 Unix 进程。它有很多信息,他的写作风格非常容易阅读和理解。这本书兼作参考指南,在某种程度上比许多实际文档更有用。


参考文献:

Check out Process.spawn, Open3, and the childprocess gem.

I can't tell exactly what you're trying to do there, but you can take control of a child process's IO in many ways.

Using Unix pipes:

readme, writeme = IO.pipe
pid = fork {
    $stdout.reopen writeme
    readme.close
    exec(...)
}

Juggling the IOs with Process.spawn:

pid = spawn(command, :err=>:out)

Or wrapping the process in POpen3:

require 'open3'
include Open3
popen3(RUBY, '-r', THIS_FILE, '-e', 'hello("Open3", true)') do
  |stdin, stdout, stderr|
  stdin.write("hello from parent")
  stdin.close_write
  stdout.read.split("\n").each do |line|
    puts "[parent] stdout: #{line}"
  end
  stderr.read.split("\n").each do |line|
    puts "[parent] stderr: #{line}"
  end

You might also consider Jesse Storimer's Working With Unix Processes. It has a lot of information and his writing style is very easy to read and understand. The book doubles as a reference guide that is somehow more useful than a lot of the actual documentation.


references:

↘人皮目录ツ 2025-01-13 03:49:41

这篇文章展示了一种在 Ruby 中临时替换 stdin 的方法:

begin 
  save_stdin = $stdin        # a dup by any other name 
  $stdin.reopen('/dev/null') # dup2, essentially 
  # do stuff
ensure 
  $stdin.reopen(save_stdin)  # restore original $stdout 
  save_stdin.close           # and dispose of the copy 
end

由于这个问题是“ruby 替换 stdin”的 Google 热门搜索之一,我希望这将帮助其他人寻找如何做到这一点。

This post shows one way to temporarily replace stdin in Ruby:

begin 
  save_stdin = $stdin        # a dup by any other name 
  $stdin.reopen('/dev/null') # dup2, essentially 
  # do stuff
ensure 
  $stdin.reopen(save_stdin)  # restore original $stdout 
  save_stdin.close           # and dispose of the copy 
end

Since this question is one of the top google hits for “ruby replace stdin,” I hope this will help others looking for how to do that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文