编辑:请,请,请阅读前回答这个帖子的底部列出的两个要求.人们不断发布他们的新宝石和图书馆等等,这显然不符合要求.
有时我想非常便宜地将一些命令行选项破解成一个简单的脚本.一个有趣的方法,没有处理getopts或解析或类似的东西,是:
...
$quiet = ARGV.delete('-d')
$interactive = ARGV.delete('-i')
...
# Deal with ARGV as usual here, maybe using ARGF or whatever.
Run Code Online (Sandbox Code Playgroud)
它不是普通的Unix选项语法,因为它将接受选项非选项命令行参数,如" myprog -i foo bar -q
",但我可以忍受.(有些人,比如Subversion的开发人员,更喜欢这个.有时我也会这样做.)
只是存在或不存在的选项不能比上述更简单地实现.(一个赋值,一个函数调用,一个副作用.)是否有一种同样简单的方法来处理带参数的选项,例如" -f
filename "?
我之前没有说过的一点,因为直到Trollop的作者提到图书馆符合"一个[800行]文件"之前我才清楚,我的目的不仅仅是清洁语法,但对于具有以下特征的技术:
整个代码可以包含在脚本文件中(不会压倒实际的脚本本身,可能只有几十行),因此可以bin
使用标准的Ruby 1.8在任何系统上删除dir中的单个文件.[5-7]安装并使用它.如果你不能编写一个没有require语句的Ruby脚本,并且解析几个选项的代码在十几行左右,那么你就不能满足这个要求.
代码很小而且非常简单,人们可以记住足够的代码来直接输入代码来完成这一操作,而不是从其他地方剪切和粘贴.想想你在一个没有互联网访问权限的防火墙服务器的控制台上的情况,你想把一个快速的脚本拼凑起来供客户使用.我不了解你,但是(除了上面的要求失败之外)记住甚至45行的简化微型optparse也不是我要做的事情.
小智 233
作为Trollop的作者,我无法相信人们认为在选项解析器中合理的东西.认真.它令人难以置信.
为什么我必须创建一个扩展其他模块的模块来解析选项?为什么我必须继承任何东西?为什么我只需要订阅一些"框架"来解析命令行?
这是上面的Trollop版本:
opts = Trollop::options do
opt :quiet, "Use minimal output", :short => 'q'
opt :interactive, "Be interactive"
opt :filename, "File to process", :type => String
end
Run Code Online (Sandbox Code Playgroud)
就是这样.opts
现在是连键的哈希:quiet
,:interactive
和:filename
.你可以用它做任何你想做的事.你会得到一个漂亮的帮助页面,格式适合你的屏幕宽度,自动短参数名称,类型检查......你需要的一切.
它是一个文件,因此如果您不想要正式的依赖项,可以将它放在lib /目录中.它有一个很容易上手的最小DSL.
LOC每个选项的人.这很重要.
ram*_*ion 76
我分享你的厌恶require 'getopts'
,主要是因为这是令人敬畏的OptionParser
:
% cat temp.rb
require 'optparse'
OptionParser.new do |o|
o.on('-d') { |b| $quiet = b }
o.on('-i') { |b| $interactive = b }
o.on('-f FILENAME') { |filename| $filename = filename }
o.on('-h') { puts o; exit }
o.parse!
end
p :quiet => $quiet, :interactive => $interactive, :filename => $filename
% ruby temp.rb
{:interactive=>nil, :filename=>nil, :quiet=>nil}
% ruby temp.rb -h
Usage: temp [options]
-d
-i
-f FILENAME
-h
% ruby temp.rb -d
{:interactive=>nil, :filename=>nil, :quiet=>true}
% ruby temp.rb -i
{:interactive=>true, :filename=>nil, :quiet=>nil}
% ruby temp.rb -di
{:interactive=>true, :filename=>nil, :quiet=>true}
% ruby temp.rb -dif apelad
{:interactive=>true, :filename=>"apelad", :quiet=>true}
% ruby temp.rb -f apelad -i
{:interactive=>true, :filename=>"apelad", :quiet=>nil}
Run Code Online (Sandbox Code Playgroud)
Cur*_*son 59
这是我经常使用的标准技术:
#!/usr/bin/env ruby
def usage(s)
$stderr.puts(s)
$stderr.puts("Usage: #{File.basename($0)}: [-l <logfile] [-q] file ...")
exit(2)
end
$quiet = false
$logfile = nil
loop { case ARGV[0]
when '-q' then ARGV.shift; $quiet = true
when '-l' then ARGV.shift; $logfile = ARGV.shift
when /^-/ then usage("Unknown option: #{ARGV[0].inspect}")
else break
end; }
# Program carries on here.
puts("quiet: #{$quiet} logfile: #{$logfile.inspect} args: #{ARGV.inspect}")
Run Code Online (Sandbox Code Playgroud)
bjj*_*jjb 34
既然没有人提到它,并且标题确实是指廉价的命令行解析,为什么不让红宝石翻译为你做这项工作呢?如果您通过-s
开关(例如,在您的shebang中),您可以免费获得污垢简单开关,分配给单字母全局变量.以下是使用该开关的示例:
#!/usr/bin/env ruby -s
puts "#$0: Quiet=#$q Interactive=#$i, ARGV=#{ARGV.inspect}"
Run Code Online (Sandbox Code Playgroud)
这是我保存为./test
和chmod它的输出+x
:
$ ./test
./test: Quiet= Interactive=, ARGV=[]
$ ./test -q foo
./test: Quiet=true Interactive=, ARGV=["foo"]
$ ./test -q -i foo bar baz
./test: Quiet=true Interactive=true, ARGV=["foo", "bar", "baz"]
$ ./test -q=very foo
./test: Quiet=very Interactive=, ARGV=["foo"]
Run Code Online (Sandbox Code Playgroud)
详情ruby -h
请见.:)
这必须和它一样便宜.如果你尝试像-:
这样的开关,它会引发一个NameError ,所以那里有一些验证.当然,在非切换参数之后你不能有任何开关,但如果你需要一些花哨的东西,你真的应该在最小的OptionParser上使用.事实上,唯一令我烦恼的是这种技术,当你访问一个未设置的全局变量时,你会得到一个警告(如果你已经启用它们),但它仍然是假的,所以它适用于一次性工具和快速脚本.
一个警告(正如FelipeC在评论中指出的那样)是你的shell可能不支持3-token shebang; 您可能需要替换/usr/bin/env ruby -w
ruby的实际路径(如/usr/local/bin/ruby -w
),或者从包装脚本或其他东西运行它.
Flo*_*ilz 13
我构建了micro-optparse,以填补这个简短但易于使用的选项解析器的明显需求.它的语法类似于Trollop,短70行.如果您不需要验证而且没有空行,则可以将其减少到45行.我认为这正是你所寻找的.
简短的例子:
options = Parser.new do |p|
p.version = "fancy script version 1.0"
p.option :verbose, "turn on verbose mode"
p.option :number_of_chairs, "defines how many chairs are in the classroom", :default => 1
p.option :room_number, "select room number", :default => 2, :value_in_set => [1,2,3,4]
end.process!
Run Code Online (Sandbox Code Playgroud)
用-h
或--help
打印脚本调用脚本
Usage: micro-optparse-example [options]
-v, --[no-]verbose turn on verbose mode
-n, --number-of-chairs 1 defines how many chairs are in the classroom
-r, --room-number 2 select room number
-h, --help Show this message
-V, --version Print version
Run Code Online (Sandbox Code Playgroud)
它检查输入是否与默认值类型相同,生成短访问器和长访问器,如果给出无效参数则打印描述性错误消息等等.
我通过使用每个选项解析器来解决我遇到的问题,比较了几个选项解析器.您可以使用这些示例和我的摘要做出信息性决策.随意添加更多实现到列表中.:)
我完全理解为什么你要避免optparse - 它可能会得到太多.但是有一些远远"轻松"的解决方案(与OptParse相比)作为库来实现,但它足够简单,可以使单个宝石安装变得有价值.
例如,查看此OptiFlag示例.只需几行处理.根据您的情况量身定制的略微截断的示例:
require 'optiflag'
module Whatever extend OptiFlagSet
flag "f"
and_process!
end
ARGV.flags.f # => .. whatever ..
Run Code Online (Sandbox Code Playgroud)
还有很多定制的例子.我记得使用另一个更容易,但它现在已经逃脱了我,但如果我找到它,我会回来在这里添加评论.
归档时间: |
|
查看次数: |
53673 次 |
最近记录: |