From: Wybo Dekker Date: 2005-06-18T05:37:58+09:00 Subject: Re: stubborn program using readline - Perl finally beaten On Sat, 18 Jun 2005, Ara.T.Howard wrote: > put another way - you want the program to ALWAYS read from EITHER a file or > stdin and you ALWAYS want to interactively (eg. from a tty) run commands after > reading the file - so why not just say that in the code? > > # > # program which does the above > # > jib:~ > cat a.rb > require 'readline' > include Readline > > inpath = ARGV.shift > infile = inpath ? open(inpath) : STDIN > > # count lines in stdin (the mail message): > n=0; while infile.gets: n+=1 end > puts "#{n} lines" > > # always get commands interactively > STDIN.reopen '/dev/tty' unless STDIN.tty? > readline("type return to quit: ") > puts "quitting..." > > you could take other approaches with dup'ing and forking but this might work > for you. This did it!! The essential line is: STDIN.reopen '/dev/tty' unless STDIN.tty? and I would say that this should actually be done in Readline at the first call of readline. I rewrote my Perl program showlines: #!/usr/bin/env ruby # # showlines - read lines from stdin (either file or pipe), # then let user interrogate lines by number require 'readline' include Readline # store and count lines in stdin: x = [] while gets: x.push($_) end puts "#{x.size} lines" # always get commands interactively STDIN.reopen '/dev/tty' unless STDIN.tty? loop do line = readline("type line number (0 to stop): ",true) if line !~ /^\d+$/ puts "Please enter a positive integer." else number = line.to_i case number when 0 puts "quitting..." exit 0 when 1..x.size puts "Line #{number}: #{x[number - 1]}" else puts "No such line." end end end and this now works as expected: $ showlines