通过命令行将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_NAME
variables捕获。
明显的缺点是你依赖于值的顺序。
如果您只需要布尔开关,请使用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" }