I have done a program that sends requests to a url and saves them in a file. The program is this, and is working perfectly:
require 'open-uri'
n = gets.to_i
out = gets.chomp
output = File.open( out, "w" )
for i in 1..n
response = open('http://slowapi.com/delay/10').read
output << (response +"\n")
puts response
end
output.close
I want to modify it so that I can execute it from command line. I must run it like this:
fle --test abc -n 300 -f output
What must I do?
3 Answers 3
Something like this should do the trick:
#!/usr/bin/env ruby
require 'open-uri'
require 'optparse'
# Prepare the parser
options = {}
oparser = OptionParser.new do |opts|
opts.banner = "Usage: fle [options]"
opts.on('-t', '--test [STRING]', 'Test string') { |v| options[:test] = v }
opts.on('-n', '--count COUNT', 'Number of times to send request') { |v| options[:count] = v.to_i }
opts.on('-f', '--file FILE', 'Output file', :REQUIRED) { |v| options[:out_file] = v }
end
# Parse our options
oparser.parse! ARGV
# Check if required options have been filled, print help and exit otherwise.
if options[:count].nil? || options[:out_file].nil?
$stderr.puts oparser.help
exit 1
end
File::open(options[:out_file], 'w') do |output|
options[:count].times do
response = open('http://slowapi.com/delay/10').read
output.puts response # Puts the response into the file
puts response # Puts the response to $stdout
end
end
-
@Skynet then you should follow these instructions on how to register
.rb
files to be opened by the ruby binary. I am not aware of any other way. If you don't want the .rb suffix, you might need to be reqired to wrap your script call in a bach file. I am not a windows user, so I don't know the details.omninonsense– omninonsense2015年10月05日 16:59:10 +00:00Commented Oct 5, 2015 at 16:59 -
can you update your code with an example of my code ? I don't understand exactly, how this works.Skynet– Skynet2015年10月06日 18:26:04 +00:00Commented Oct 6, 2015 at 18:26
Here's a more idiomatic way of writing your code:
require 'open-uri'
n = gets.to_i
out = gets.chomp
File.open(out, 'w') do |fo|
n.times do
response = open('http://slowapi.com/delay/10').read
fo.puts response
puts response
end
end
This uses File.open
with a block, which allows Ruby to close the file once the block exits. It's a much better practice than assigning the file handle to a variable and use that to close
the file later.
How to handle passing in variables from the command-line as options is handled in the other answers.
-
There's a small typo in the code example:
n.times
should ben.times do
. I tried to edit it, but it wouldn't let me because the edit was under 6 characters. :(omninonsense– omninonsense2015年10月06日 23:52:25 +00:00Commented Oct 6, 2015 at 23:52 -
@destielstarship, It's good that it didn't let you. It's considered bad form to edit people's code. Instead you should simply point it out in a comment. It's OK to adjust spelling, grammar and content for clarity but code and data are sacred.the Tin Man– the Tin Man2015年10月06日 23:54:19 +00:00Commented Oct 6, 2015 at 23:54
-
Oh, I wasn't aware of that SO convention! I apologise. :-)omninonsense– omninonsense2015年10月06日 23:57:48 +00:00Commented Oct 6, 2015 at 23:57
The first step would be to save you program in a file, add #!/usr/bin/env ruby
at the top and chmod +x yourfilename
to be able to execute your file.
Now you are able to run your script from the command line.
Secondly, you need to modify your script a little bit to pick up command line arguments. In Ruby, the command line arguments are stored inside ARGV
, so something like
ARGV.each do|a|
puts "Argument: #{a}"
end
allows you to retrieve command line arguments.
-
@MaxWilliams I also believe, they could just use
#!/usr/bin/env ruby
, but otherwise it is a good remark in case ruby was installed through MRI or similar.omninonsense– omninonsense2015年10月05日 16:37:56 +00:00Commented Oct 5, 2015 at 16:37 -
Walking through
ARGV
is definitely old-school. Don't do it unless you absolutely have to. Instead, take advantage of using Ruby's built-in Option Parser class.the Tin Man– the Tin Man2015年10月05日 20:29:02 +00:00Commented Oct 5, 2015 at 20:29
irb
to run each and every line of your code