我在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'
答案 0 :(得分:441)
这样的事情:
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
答案 1 :(得分:180)
不要重新发明轮子;看看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)
答案 2 :(得分:25)
不幸的是,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会抱怨不存在的选项-agreed
,因此将其作为切换到cmd invokation。在以下情况下您不需要它:
> 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来实现选项解析器。
快乐的黑客攻击!
答案 3 :(得分:1)
您也可以试用var sf = new StackTrace().GetFrame(1);
var callingMethodName = sf.GetMethod().Name;
。它是一个非常新的和积极的发展。但是有一些稳定的版本可供使用。这是git repo:https://github.com/anshulverma/cliqr
查看示例文件夹,了解如何使用它。
答案 4 :(得分:1)
除非它是最简单的情况,否则只有一种在Ruby中使用命令行选项的合理方法。它被称为docopt并记录为here。
令人惊奇的是它的简洁性。 您需要做的就是指定" help"您的命令的文本。您在那里写的内容将由独立(!)ruby库自动解析。
来自example:
#!/usr/bin/env ruby
require 'docopt.rb'
doc = <<DOCOPT
Usage: #{__FILE__} --help
#{__FILE__} -v...
#{__FILE__} go [go]
#{__FILE__} (--path=<path>)...
#{__FILE__} <file> <file>
Try: #{__FILE__} -vvvvvvvvvv
#{__FILE__} go go
#{__FILE__} --path ./here --path ./there
#{__FILE__} this.txt that.txt
DOCOPT
begin
require "pp"
pp Docopt::docopt(doc)
rescue Docopt::Exit => e
puts e.message
end
输出:
$ ./counted_example.rb -h
Usage: ./counted_example.rb --help
./counted_example.rb -v...
./counted_example.rb go [go]
./counted_example.rb (--path=<path>)...
./counted_example.rb <file> <file>
Try: ./counted_example.rb -vvvvvvvvvv
./counted_example.rb go go
./counted_example.rb --path ./here --path ./there
./counted_example.rb this.txt that.txt
$ ./counted_example.rb something else
{"--help"=>false,
"-v"=>0,
"go"=>0,
"--path"=>[],
"<file>"=>["something", "else"]}
$ ./counted_example.rb -v
{"--help"=>false, "-v"=>1, "go"=>0, "--path"=>[], "<file>"=>[]}
$ ./counted_example.rb go go
{"--help"=>false, "-v"=>0, "go"=>2, "--path"=>[], "<file>"=>[]}
享受!
答案 5 :(得分:0)
在命令行上运行此代码并输入N:
的值N = gets; 1.step(N.to_i, 1) { |i| print "hello world\n" }
答案 6 :(得分:0)
您应该尝试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!
答案 7 :(得分:0)
我知道这很老,但是这里没有提到 getoptlong ,它可能是当今解析命令行参数的最佳方法。
我强烈推荐getoptlong。它非常易于使用,并且像魅惑一样工作。 这是从上面的链接中提取的示例
require 'getoptlong'
opts = GetoptLong.new(
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
[ '--repeat', '-n', GetoptLong::REQUIRED_ARGUMENT ],
[ '--name', GetoptLong::OPTIONAL_ARGUMENT ]
)
dir = nil
name = nil
repetitions = 1
opts.each do |opt, arg|
case opt
when '--help'
puts <<-EOF
hello [OPTION] ... DIR
-h, --help:
show help
--repeat x, -n x:
repeat x times
--name [name]:
greet user by name, if name not supplied default is John
DIR: The directory in which to issue the greeting.
EOF
when '--repeat'
repetitions = arg.to_i
when '--name'
if arg == ''
name = 'John'
else
name = arg
end
end
end
if ARGV.length != 1
puts "Missing dir argument (try --help)"
exit 0
end
dir = ARGV.shift
Dir.chdir(dir)
for i in (1..repetitions)
print "Hello"
if name
print ", #{name}"
end
puts
end
您可以这样称呼它
ruby hello.rb -n 6 --name -- /tmp
在这种情况下,我认为最好的选择是按照建议的in this answer
使用YAML文件