开发者

dropping user to IRB after reading from pipe

开发者 https://www.devze.com 2023-02-02 09:36 出处:网络
I have this script that drops the user to an IRB session when executed. All good, but when I use *nix pipes to get the input (e.g. with cat), the IRB session ends immediately.

I have this script that drops the user to an IRB session when executed.

All good, but when I use *nix pipes to get the input (e.g. with cat), the IRB session ends immediately.

I could reduce the script (let's call it myscript.rb) to the following:

require 'irb'

if $stdin.stat.size > 0
  @text = $stdin.read 
else
  @text= "nothing"
end

ARGV.clear
IRB.start

When executed like: ruby myscript.rb, I end up in the IRB session (as expected).

But (assuming foo.txt exists in the cwd): cat foo.txt | ruby myscript.rb will just print the IRB prompt and then the IRB session is closed (I'm being dropped to $bash).

Any known workarounds or ideas?

BTW: it has the same behavior on ruby 1.8.7 as well as on 1.9.2开发者_StackOverflow.


I think your problem is that when you pipe to your script STDIN will be the stream from your file, so when when you start IRB it will read from the same stream, but notice that it's at its end, and quit, just like it would when you type ctrl-D (which is a manual end of file signal).

You can reopen STDIN to read from the tty (i.e. the keyboard) like this:

STDIN.reopen(File.open('/dev/tty', 'r'))

but it looks a bit weird for me, I don't get the proper IRB promt. IRB works though.


@Theo identified the problem.

Also, requiring irb before IRB.start will fix missing IRB settings. In the end, the code looks like this:

if $stdin.stat.size > 0
  @text = $stdin.read
  $stdin.reopen(File.open("/dev/tty", "r"))
else
  @text= "nothing"
end

require 'irb'
ARGV.clear
IRB.start


$stdin.read reads your input before IRB has a chance to read it (if you're trying to force IRB to execute commands from stdin).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号