【问题标题】:Execute ruby subprocess which requires interactive input执行需要交互式输入的 ruby​​ 子进程
【发布时间】:2013-05-05 05:06:23
【问题描述】:

我需要从 ruby​​ 启动一个子进程,它接管然后返回控制权。 这个子进程需要来自用户的交互式输入,所以它的 io 应该绑定到 stdin stdout 和 stderr。此外,它会根据情况要求输入更改。

这样的程序的一个例子是 TeX,我会在一个文件上启动它,但在这个过程中 TeX 可能会遇到一个用户错误,它必须询问用户如何修复。

基本上我正在寻找可重入版本的 exec。

PS

对于那些不能仔细阅读的人,让我重申一下。

这个子流程需要用户的交互输入

这意味着如果 ruby​​ 程序在 tty 中运行,那么它的输出会发送到 tty 而不是 Ruby 程序,并且它的输入来自 tty,而不是 Ruby 程序。

换句话说: 基本上我正在寻找可重入版本的 exec。

我以 TeX 为例,所以让我给你看一个例子。我在Sample Tex 上找到了一份 TeX 样本。我打算输入一个错误,但似乎我不必让它阻塞我的系统。保存在sample1.tex、sample2.tex、sample3.tex中。

现在我想运行这段 ruby​​ 代码:

files=["sample1.tex","sample2.tex","sample3.tex"]
files.each{|file|
     # It is really a latex command.
     commmand_that_I_am_looking_for("latex #{file}")
 }

当我运行这段代码时,我应该在终端中看到三倍的东西:

有关乳胶程序、处理进度等的一般信息。

! LaTeX Error: File `html.sty' not found.

Type X to quit or <RETURN> to proceed,
or enter new name. (Default extension: sty)
Enter file name: 

程序在每三次都等待用户输入内容的位置。

【问题讨论】:

  • 您希望实现的目标有点令人困惑。您想以编程方式控制子进程的交互式输入/输出吗?如果你这样做了,那么就有一个标准的 PTY 模块来完成这些任务。见ruby-doc.org/stdlib/libdoc/pty/rdoc/PTY.html
  • 我不明白这有多棘手。显而易见的Kernel::system 怎么不能做你想做的事?它运行您在子shell 中传递的命令,该子shell 继承您的ruby 进程的stdin/stdout/stderr;它阻塞等待子进程退出。

标签: ruby input subprocess


【解决方案1】:

您可以将forkexec 配对:

Process.fork { exec('./somescript') }
Process.wait

Process.wait 确保您等待子流程完成。

【讨论】:

    【解决方案2】:

    Ruby 标准库有一个特殊的命令可以满足您的需求。它被称为open3。这是其文档中的一个示例:

    Open3.popen3("pwd", :chdir=>"/") {|stdin, stdout, stderr, thread|
      p stdout.read.chomp #=> "/"
    }
    

    【讨论】:

    • 向我解释您的示例程序“pwd”需要什么样的用户输入?
    • @Mouse.The.Lucky.Dog 这里几乎每个人都在努力帮助他人并互相学习。说某人愚蠢是没有建设性的。解释你如何以及为什么认为他们是错的。尽量保持礼貌,不是每个人都能看到你所看到的,也没有人欠你时间或注意力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    • 2021-06-20
    • 2018-05-08
    • 1970-01-01
    相关资源
    最近更新 更多