dropping user to IRB after reading from pipe
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).
精彩评论