【问题标题】:Calling a Perl script from Ruby从 Ruby 调用 Perl 脚本
【发布时间】:2013-01-08 07:10:55
【问题描述】:

我目前正在尝试找出一种从 Ruby 调用 Perl 脚本的方法,并让它像我在终端中一样输出,并允许我在需要时提供输入。

我已经想出了如何做到这一点并在事后获得输入,但由于 Perl 脚本仍在运行,我无法运行其他任何东西。

我应该注意我不能编辑 Perl 脚本。提供了这些脚本,并制作了这个 Ruby 脚本,以使运行所有 Perl 脚本的过程更容易,并确保它们的顺序正确。

upgradestatus =  `#{upgradearray[arraylocation]}`

这将是我的代码的相关部分。我尝试了其他一些如何做到这一点的变体,但每次我都会遇到相同的情况。当脚本开始运行时,它需要输入,所以它就在那里。

【问题讨论】:

  • 您的问题需要更清楚。也许您应该向我们展示您所做的事情或发布伪代码,以便我们可以看到您期望的输入、输出和控制流。
  • 子进程通常会继承其父进程的句柄,包括 STDIN。这够好吗?
  • 你能用this之类的东西从命令行调用perl吗?
  • 我稍微更新了一下。除非我从那个链接中遗漏了一些东西。这些都是调用脚本的不同方式,但在脚本运行时不会输出。

标签: ruby perl bash


【解决方案1】:

您无法使用反引号、%x 或作为普通子 shell 执行您想要的操作,因为它们无法查看子命令的输出。

您可以使用 Open3 的 popen2popen3 方法来实现。它们允许您发送到被调用程序的 STDIN 流,并从 STDOUT 接收数据。 popen3 还可以让您查看/捕获 STDOUT 流。不幸的是,在被调用的程序返回其信息之前,您通常必须先发送然后关闭 STDIN 流,这可能是 Perl 脚本的情况。

如果您需要更多控制,请考虑使用 Ruby 的内置 Pty 模块。它旨在让您通过脚本机制与正在运行的应用程序对话。您必须设置代码来查找提示,然后通过发回适当的数据来响应它们。它可以很简单,也可以是主要的 PITA,具体取决于您正在与之交谈的代码。

这是open 命令的示例:

PTY.open {|m, s|
p m      #=> #<IO:masterpty:/dev/pts/1>
p s      #=> #<File:/dev/pts/1>
p s.path #=> "/dev/pts/1"
}

# Change the buffering type in factor command,
# assuming that factor uses stdio for stdout buffering.
# If IO.pipe is used instead of PTY.open,
# this code deadlocks because factor's stdout is fully buffered.
require 'io/console' # for IO#raw!
m, s = PTY.open
s.raw! # disable newline conversion.
r, w = IO.pipe
pid = spawn("factor", :in=>r, :out=>s)
r.close
s.close
w.puts "42"
p m.gets #=> "42: 2 3 7\n"
w.puts "144"
p m.gets #=> "144: 2 2 2 2 3 3\n"
w.close
# The result of read operation when pty slave is closed is platform
# dependent.
ret = begin
        m.gets          # FreeBSD returns nil.
    rescue Errno::EIO # GNU/Linux raises EIO.
        nil
    end
p ret #=> nil

【讨论】:

  • 感谢您的帮助。如果我理解正确,这看起来应该可以工作。所需的输入只是对可能的错误做出反应并确认应该运行脚本以便易于编程。但是当我尝试运行您输入的内容时。我得到“test.rb:1: uninitialized constant PTY (名称错误)"
  • 也许你应该试试require 'pty'
  • 这似乎解决方案应该工作,但我很难让它工作。但是我想出了一个对我有用的解决方案。我生成了脚本。该脚本将可以通过一个简单的 sql 命令检测到,因此我只需让它循环并休眠几秒钟,直到它不再检测到它,然后再继续。不是最优雅的解决方案,而是为了速度,所以这个脚本是可用的,然后我可以稍后更新它,所以它是完全自动化的。我能够开始工作的最佳解决方案。
猜你喜欢
  • 1970-01-01
  • 2012-07-23
  • 2013-12-03
  • 1970-01-01
  • 2014-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多