2010-11-22 155 views
207

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

# Source server connection info. 
SOURCE_NAME = '[email protected]' 
SOURCE_HOST = 'mail.example.com' 
SOURCE_PORT = 143 
SOURCE_SSL = false 
SOURCE_USER = 'username' 
SOURCE_PASS = 'password' 

# Destination server connection info. 
DEST_NAME = '[email protected]' 
DEST_HOST = 'imap.gmail.com' 
DEST_PORT = 993 
DEST_SSL = true 
DEST_USER = '[email protected]' 
DEST_PASS = 'password' 

回答

368

事情是这样的:

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 
+62

我想明确指出,ARGV [0]不指向程序名,因为一些其他语言做。要获取程序名称,请参阅http://stackoverflow.com/questions/4834821/how-can-i-get-the-name-of-the-command-called-for-usage-prompts-in-ruby – 2015-05-01 18:37:47

161

不要推倒重来;检查Ruby的方式 - 酷的OptionParser库。

它提供标记/开关解析,带有可选或必需值的参数,可将参数列表解析为单个选项,并可为您生成帮助。此外,如果您传递的任何信息都非常静态,即不会在运行之间更改,请将其放入一个经过分析的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: [email protected] 
dest_host: imap.gmail.com 
dest_port: 993 
dest_ssl: true 
dest_user: [email protected] 
dest_pass: password 

这将让你轻松地生成一个YAML文件:

require 'yaml' 

yaml = { 
    'dest_name' => '[email protected]', 
    'dest_host' => 'imap.gmail.com', 
    'dest_port' => 993, 
    'dest_ssl' => true, 
    'dest_user' => '[email protected]', 
    'dest_pass' => 'password' 
} 

puts YAML.dump(yaml) 
+1

OptParse链接已死亡。尝试http://ruby-doc.org/stdlib-1.9.3/libdoc/optparse/rdoc/OptionParser.html – Casey 2012-08-23 17:55:06

+6

优秀的答案;可能值得补充的是,在完成选项分析后,“ARGV”只包含操作数(如果有的话)(即剩余的非选项参数)。 – mklement0 2015-07-13 22:07:40

23

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

> awk -v a=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 

红宝石存储所有CMD参数的ARGV数组中的脚本名称本身可以使用$PROGRAM_NAME变量被捕获。

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

如果您只需要布尔交换机使用Ruby解释器的选项-s

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

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

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

缺点是您会混淆全局变量并且只有逻辑真/假值。

您可以从环境变量访问值:

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

缺点都存在这里,你必须设置所有变量的脚本调用之前(仅适用于你的Ruby程序)或将它们导出(如炮弹BASH):

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

在后一种情况下,你的数据将是可读的每个人都在同一个shell会话和所有子过程,它可以是一个严重的安全含义。

至少您可以使用getoptlongoptparse来实现选项解析器。

快乐黑客!

1

运行在命令行上的代码,输入N的值:

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