从从 stdin 读取的 Ruby 脚本调用时,Pry 不会停止

Pry not stopping when called from a Ruby script that reads from stdin

我创建了一个控制台 Ruby 脚本,它使用 ARGF 从文件或标准输入加载数据,然后调用 Pry。

当我传递一个文件(Pry 暂停)但是当我使用标准输入传递我的数据时失败(Pry 不会停止,只是退出 Ruby)时这很有效。

这很奇怪,有人知道为什么吗?我想通过 stdin 传递数据并让 Pry 暂停。

看,一个示例脚本:

require 'rubygems'
require 'pry'


def pry_it(str)
    binding.pry
end

pry_it(ARGF.read)

当我使用 ARGV 中的文件调用此应用程序时,我得到了正确的响应 - pry pausing

% bundle exec ruby pry_test.rb file.txt

From: /Users/wilcoxr/Development/json_pry/pry_test.rb @ line 8 Object#pry_it:

    6: def pry_it(str)
    7:
 => 8:  binding.pry
    9: end

[1] pry(main)>

太棒了!我可以随心所欲地执行 Pry 命令

当我尝试使用 STDIN 将数据发送到我的工具时:

% cat file.txt | bundle exec ruby pry_test.rb

From: /Users/wilcoxr/Development/json_pry/pry_test.rb @ line 8 Object#pry_it:

    6: def pry_it(str)
    7:
 => 8:  binding.pry
    9: end

[1] pry(main)>
% 

仔细观察:注意我回到了 shell 提示符,而不是在 IRB 中暂停。诡异的!我不明白为什么我会出现这种行为....

尝试 ARGF 简单:

require 'rubygems'
require 'pry'
binding.pry

现在 IO 操作没有被 ARGF.read 内部覆盖,很明显这里出了什么问题。 ARGF 被“粘”到 STDIN,因此传递给 STDIN 的任何内容都直接进入 pry 的输入。

我不太清楚,你的file.txt中有什么指令强制 pry 退出,但是有一个。


更新

看起来 如果 Ruby 脚本在 stdin 上产生任何东西(例如通过管道)$stdinSTDIN 被设置到这个管道,搞乱了 pry 的“我从哪里 运行” 检测。

我想到了这个不太优雅的解决方案:

# read input from ARGF
text = ARGF.read

# prepare new stdin to satisfy pry
pry_fd_stdin = IO.sysopen("/dev/tty")
pry_stdin = IO.new(pry_fd_stdin, "r")

# load pry and cheat it with our stdio
require 'pry'
Pry.config.input = pry_stdin

binding.pry

此解决方案存在一些问题(例如,撬提示仅在 输入 后显示)。