通过命令行将variables传递给Ruby脚本

我在Windows上安装了RubyInstaller,并且正在运行IMAP Sync,但是我需要使用它来同步数百个帐户。 如果我可以通过命令行将这些variables传递给它,我可以更好地自动化整个过程。

# Source server connection info. SOURCE_NAME = 'username@example.com' SOURCE_HOST = 'mail.example.com' SOURCE_PORT = 143 SOURCE_SSL = false SOURCE_USER = 'username' SOURCE_PASS = 'password' # Destination server connection info. DEST_NAME = 'username@gmail.com' DEST_HOST = 'imap.gmail.com' DEST_PORT = 993 DEST_SSL = true DEST_USER = 'username@gmail.com' DEST_PASS = 'password' 

像这样的东西:

 ARGV.each do|a| puts "Argument: #{a}" end 

然后

 $ ./test.rb "test1 test2" 

要么

 v1 = ARGV[0] v2 = ARGV[1] puts v1 #prints test1 puts v2 #prints test2 

不要重新发明轮子; 检查Ruby的方式酷的OptionParser库。

它提供了标志/开关的parsing,带有可选或必需值的参数,可以将参数列表parsing为一个选项,并可以为您生成帮助。

另外,如果你传递的任何信息都是非常静态的,那么在运行之间不会改变,把它放到一个被parsing的YAML文件中。 这样,你可以在命令行上每次都改变一些东西,偶尔在你的代码之外改变的东西也会改变。 数据和代码的分离很好的维护。

以下是一些可以玩的样品:

 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'] 

如果您的目标非常静态,这是一个示例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 

这会让你轻松的生成一个YAML文件:

 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) 

不幸的是,Ruby不支持像AWK这样的传递机制:

 > awk -va=1 'BEGIN {print a}' > 1 

这意味着你不能直接将命名值传递给你的脚本。

使用cmd选项可能有所帮助:

 > ruby script.rb val_0 val_1 val_2 # script.rb puts ARGV[0] # => val_0 puts ARGV[1] # => val_1 puts ARGV[2] # => val_2 

Ruby将所有cmd参数存储在ARGV数组中,脚本名本身可以使用$PROGRAM_NAMEvariables捕获。

明显的缺点是你依赖于值的顺序。

如果您只需要布尔开关,请使用Ruby解释器的-s选项:

 > ruby -s -e 'puts "So do I!" if $agreed' -- -agreed > So do I! 

请注意--开关,否则Ruby会抱怨一个不存在的选项 – -agreed ,所以把它作为切换到您的cmd invokation。 在以下情况下不需要它:

 > ruby -s script_with_switches.rb -agreed > So do I! 

缺点是你混淆了全局variables,只有逻辑真/假值。

您可以从环境variables中访问值:

 > FIRST_NAME='Andy Warhol' ruby -e 'puts ENV["FIRST_NAME"]' > Andy Warhol 

缺点是在这里,你必须在脚本调用之前设置所有的variables(仅适用于你的ruby进程)或导出它们(像BASH这样的shell):

 > export FIRST_NAME='Andy Warhol' > ruby -e 'puts ENV["FIRST_NAME"]' 

在后一种情况下,您的数据在同一个shell会话和所有subprocess中对每个人都是可读的,这可能是一个严重的安全隐患。

至less你可以使用getoptlong和optparse实现一个选项parsing器。

快乐的黑客!

你也可以试试cliqr 。 它是非常新的和积极的发展。 但是有稳定的版本可以使用。 这是git repo: https : //github.com/anshulverma/cliqr

看看示例文件夹,了解如何使用它。

在命令行上运行这个代码并inputN的值:

 N = gets; 1.step(N.to_i, 1) { |i| print "hello world\n" }