Pass variables to Ruby script via command line
Something like this:
ARGV.each do|a| puts "Argument: #{a}"end
then
$ ./test.rb "test1 test2"
or
v1 = ARGV[0]v2 = ARGV[1]puts v1 #prints test1puts v2 #prints test2
Don't reinvent the wheel; check out Ruby's way-cool OptionParser library.
It offers parsing of flags/switches, parameters with optional or required values, can parse lists of parameters into a single option and can generate your help for you.
Also, if any of your information being passed in is pretty static, that doesn't change between runs, put it into a YAML file that gets parsed. That way you can have things that change every time on the command-line, and things that change occasionally configured outside your code. That separation of data and code is nice for maintenance.
Here are some samples to play with:
require 'optparse'require 'yaml'options = {}OptionParser.new do |opts| opts.banner = "Usage: example.rb [options]" opts.on('-n', '--sourcename NAME', 'Source name') { |v| options[:source_name] = v } opts.on('-h', '--sourcehost HOST', 'Source host') { |v| options[:source_host] = v } opts.on('-p', '--sourceport PORT', 'Source port') { |v| options[:source_port] = v }end.parse!dest_options = YAML.load_file('destination_config.yaml')puts dest_options['dest_name']
This is a sample YAML file if your destinations are pretty static:
--- dest_name: username@gmail.comdest_host: imap.gmail.comdest_port: 993dest_ssl: truedest_user: username@gmail.comdest_pass: password
This will let you easily generate a YAML file:
require 'yaml'yaml = { 'dest_name' => 'username@gmail.com', 'dest_host' => 'imap.gmail.com', 'dest_port' => 993, 'dest_ssl' => true, 'dest_user' => 'username@gmail.com', 'dest_pass' => 'password'}puts YAML.dump(yaml)
Unfortunately, Ruby does not support such passing mechanism as e.g. AWK:
> awk -v a=1 'BEGIN {print a}'> 1
It means you cannot pass named values into your script directly.
Using cmd options may help:
> ruby script.rb val_0 val_1 val_2# script.rbputs ARGV[0] # => val_0puts ARGV[1] # => val_1puts ARGV[2] # => val_2
Ruby stores all cmd arguments in the ARGV
array, the scriptname itself can be captured using the $PROGRAM_NAME
variable.
The obvious disadvantage is that you depend on the order of values.
If you need only Boolean switches use the option -s
of the Ruby interpreter:
> ruby -s -e 'puts "So do I!" if $agreed' -- -agreed> So do I!
Please note the --
switch, otherwise Ruby will complain about a nonexistent option -agreed
, so pass it as a switch to your cmd invokation. You don't need it in the following case:
> ruby -s script_with_switches.rb -agreed> So do I!
The disadvantage is that you mess with global variables and have only logical true/false values.
You can access values from environment variables:
> FIRST_NAME='Andy Warhol' ruby -e 'puts ENV["FIRST_NAME"]'> Andy Warhol
Drawbacks are present here to, you have to set all the variables before the script invocation (only for your ruby process) or to export them (shells like BASH):
> export FIRST_NAME='Andy Warhol'> ruby -e 'puts ENV["FIRST_NAME"]'
In the latter case, your data will be readable for everybody in the same shell session and for all subprocesses, which can be a serious security implication.
And at least you can implement an option parser using getoptlong and optparse.
Happy hacking!