我已经在Windows上安装了RubyInstaller,我正在运行IMAP Sync,但我需要使用它来同步数百个帐户。如果我可以通过命令行将这些变量传递给它,我可以更好地自动化整个过程。
# 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'
您应该尝试console_runner gem。这个宝石使您的纯Ruby代码可以从命令行执行。你所需要的就是在你的代码中添加YARD注释:
# @runnable This tool can talk to you. Run it when you are lonely.
# Written in Ruby.
class MyClass
def initialize
@hello_msg = 'Hello'
@bye_msg = 'Good Bye'
end
# @runnable Say 'Hello' to you.
# @param [String] name Your name
# @param [Hash] options options
# @option options [Boolean] :second_meet Have you met before?
# @option options [String] :prefix Your custom prefix
def say_hello(name, options = {})
second_meet = nil
second_meet = 'Nice to see you again!' if options['second_meet']
prefix = options['prefix']
message = @hello_msg + ', '
message += "#{prefix} " if prefix
message += "#{name}. "
message += second_meet if second_meet
puts message
end
end
然后从控制台运行它:
$ c_run /projects/example/my_class.rb say_hello -n John --second-meet --prefix Mr.
-> Hello, Mr. John. Nice to see you again!
不要白费力气;看看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: 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 -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
Ruby将所有cmd参数存储在ARGV数组中,脚本名本身可以使用$PROGRAM_NAME变量捕获。
明显的缺点是依赖于值的顺序。
如果你只需要布尔开关,使用Ruby解释器的选项-s:
> ruby -s -e 'puts "So do I!" if $agreed' -- -agreed
> So do I!
请注意——开关,否则Ruby会抱怨一个不存在的选项-商定,因此将它作为开关传递给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这样的shell):
> export FIRST_NAME='Andy Warhol'
> ruby -e 'puts ENV["FIRST_NAME"]'
在后一种情况下,您的数据对于同一shell会话中的每个人以及所有子进程都是可读的,这可能是一个严重的安全隐患。
至少您可以使用getoptlong和optparse实现一个选项解析器。
黑客快乐!