Pass variables to Ruby script via command line Pass variables to Ruby script via command line ruby ruby

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!