I have been trying to figure out how, while using OptionParser to be able to check for files being input on the command line and if they don’t exist, check other input streams (like Bash). This initially wasn’t very easy since input streams are blocking. So with a little help from friends (thanks roberto), I was able to use his method of non-blocking IO and wrap it in a begin/rescue block. I also took a little advice given in this Stack Overflow question called Best Practices with STDIN in Ruby.
First we need to get the file list off the command line and assume that anything left are files.
...
end
@opts.parse!(args)
@files = args
Since we are using threads, I open up a thread for STDIN and killed it when we run out of input.
threads = Array.new
# Set $stdin to be non-blocking
$stdin.fcntl(Fcntl::F_SETFL,Fcntl::O_NONBLOCK)
threads[0] = Thread.new {
begin
$stdin.each_line { |line| puts "STDIN: #{line}" }
rescue Errno::EAGAIN
threads.delete(0) # Remove this thread since we won't be reading from $stdin
end
}.run
Now its time for the files.
threads.push Thread.new {
# do stuff with 'file'
}
end
# Put it all together and have the threads run
threads.each { |thread| thread.join }
Using these code snippets, you will be able to use input from both files on the command line and STDIN:
- $ myscript.rb file1 file2
- $ cat foo | myscript.rb file1 file2
- $ myscript.rb file1 file2 < foo
No related posts.

Pingback: Tweets that mention Multiple Input Locations From Bash Into Ruby | Erics Tech Blog -- Topsy.com