当前位置:  开发笔记 > 编程语言 > 正文

如何将命令行参数传递给rake任务

如何解决《如何将命令行参数传递给rake任务》经验,为你挑选了12个好方法。

我有一个rake任务需要将值插入多个数据库.

我想从命令行或另一个 rake任务将此值传递给rake任务.

我怎样才能做到这一点?



1> Nick Desjard..:

您可以通过向任务调用添加符号参数来在rake中指定正式参数.例如:

require 'rake'

task :my_task, [:arg1, :arg2] do |t, args|
  puts "Args were: #{args}"
end

task :invoke_my_task do
  Rake.application.invoke_task("my_task[1, 2]")
end

# or if you prefer this syntax...
task :invoke_my_task_2 do
  Rake::Task[:my_task].invoke(3, 4)
end

# a task with prerequisites passes its 
# arguments to it prerequisites
task :with_prerequisite, [:arg1, :arg2] => :my_task #<- name of prerequisite task

# to specify default values, 
# we take advantage of args being a Rake::TaskArguments object
task :with_defaults, :arg1, :arg2 do |t, args|
  args.with_defaults(:arg1 => :default_1, :arg2 => :default_2)
  puts "Args with defaults were: #{args}"
end

然后,从命令行:

> rake my_task[1,2]
Args were: {:arg1=>"1", :arg2=>"2"}

> rake "my_task[1, 2]"
Args were: {:arg1=>"1", :arg2=>"2"}

> rake invoke_my_task
Args were: {:arg1=>"1", :arg2=>"2"}

> rake invoke_my_task_2
Args were: {:arg1=>3, :arg2=>4}

> rake with_prerequisite[5,6]
Args were: {:arg1=>"5", :arg2=>"6"}

> rake with_defaults
Args with defaults were: {:arg1=>:default_1, :arg2=>:default_2}

> rake with_defaults['x','y']
Args with defaults were: {:arg1=>"x", :arg2=>"y"}

如第二个示例所示,如果要使用空格,则必须使用目标名称周围的引号来防止shell拆分空间处的参数.

查看rake.rb中的代码,看起来rake不会解析任务字符串来提取先决条件的参数,所以你不能这样做task :t1 => "dep[1,2]".为先决条件指定不同参数的唯一方法是在依赖任务操作中显式调用它,如:invoke_my_task:invoke_my_task_2.

请注意,某些shell(如zsh)要求您转义括号: rake my_task\['arg1'\]


请注意,zsh无法正确解析命令行参数(`zsh:no matches found:...`),因此您需要转义括号:`rake my_task\['arg1'\]`.来自http://robots.thoughtbot.com/post/18129303042/how-to-use-arguments-in-a-rake-task
注意:根据rake,不推荐使用这种在任务中接受变量的语法:`警告:'task:t,arg,:needs => [deps]'已弃用.请改用'task:t,[args] => [deps]'
要在命名空间内调用任务,请执行以下操作:Rake :: Task ['namespace:task'].invoke
@SethBro是的。如果您的评论没有被隐藏在“查看更多评论”链接的后面,那么我不会浪费10分钟来完成这项工作。

2> Blair Anders..:

选项和依赖项需要在数组内部:

namespace :thing do
  desc "it does a thing"
  task :work, [:option, :foo, :bar] do |task, args|
    puts "work", args
  end

  task :another, [:option, :foo, :bar] do |task, args|
    puts "another #{args}"
    Rake::Task["thing:work"].invoke(args[:option], args[:foo], args[:bar])
    # or splat the args
    # Rake::Task["thing:work"].invoke(*args)
  end

end

然后

rake thing:work[1,2,3]
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}

rake thing:another[1,2,3]
=> another {:option=>"1", :foo=>"2", :bar=>"3"}
=> work: {:option=>"1", :foo=>"2", :bar=>"3"}

注意:变量task是任务对象,除非您了解/关心Rake内部,否则不是很有帮助.

铁路注意:

如果从rails运行任务,最好通过添加来预加载环境,=> [:environment]这是设置相关任务的一种方法.

  task :work, [:option, :foo, :bar] => [:environment] do |task, args|
    puts "work", args
  end


遗憾的是,zsh无法正确解析调用,你需要在zsh上键入命令,如下所示:`rake thing:work\[1,2,3 \]`,或者这个'rake'的东西:work [1,2,3] ]'`
另外,请确保不要在参数之间使用空格.例如,不要这样做:`rake thing:work [1,2,3]`因为它不起作用你会得到一个错误`不知道如何构建任务
另外,请确保将参数括在string中.例如,从你的命令行运行rake任务就像这样`rake thing:work'[1,2,3]'`
除了注释不说明“ t”表示“任务”之外,为什么不只使用“任务”作为参数名称呢?

3> timurb..:

除了回答kch(我没有找到如何发表评论,抱歉):

您不必ENVrake命令之前将变量指定为变量.您可以像往常一样将它们设置为通常的命令行参数:

rake mytask var=foo

并从你的rake文件中访问那些作为ENV变量,如:

p ENV['var'] # => "foo"


这是IMO最好的最简单的答案。它立即起作用。p到底是什么意思?

4> Tombart..:

如果你想传递命名参数(例如标准OptionParser),你可以使用这样的东西:

$ rake user:create -- --user test@example.com --pass 123

请注意--,这是绕过标准Rake参数所必需的.应与耙工作0.9.x版本,<= 10.3.x中.

较新的Rake改变了它的解析--,现在你必须确保它没有传递给OptionParser#parse方法,例如parser.parse!(ARGV[2..-1])

require 'rake'
require 'optparse'
# Rake task for creating an account

namespace :user do |args|
  desc 'Creates user account with given credentials: rake user:create'
  # environment is required to have access to Rails models
  task :create do
    options = {}
    OptionParser.new(args) do |opts|
      opts.banner = "Usage: rake user:create [options]"
      opts.on("-u", "--user {username}","User's email address", String) do |user|
        options[:user] = user
      end
      opts.on("-p", "--pass {password}","User's password", String) do |pass|
        options[:pass] = pass
      end
    end.parse!

    puts "creating user account..."
    u = Hash.new
    u[:email] = options[:user]
    u[:password] = options[:pass]
    # with some DB layer like ActiveRecord:
    # user = User.new(u); user.save!
    puts "user: " + u.to_s
    puts "account created."
    exit 0
  end
end

exit 最后将确保额外的参数不会被解释为Rake任务.

参数的快捷方式也应该有效:

 rake user:create -- -u test@example.com -p 123

当rake脚本看起来像这样时,也许是时候寻找另一个允许这个开箱即用的工具了.


从我的角度来看,这确实是最好的答案.绕过环境变量kludges,使用任务参数的奇怪语法,标准`--option-names`的额外好处.我唯一的建议是使用`exit`而不是`abort`,因为`abort`会给你一个返回码为1的shell.如果rake任务是更高级别脚本的一部分,则更常见的是假设非零退出是某种类型的错误.
Rake解析ARGV的方式在`10.4.1`中改变了,并在'10.4.2`中恢复.https://github.com/ruby/rake/commit/86af0ef6d793b85068a44fb3407b23c9c9b09bc7

5> Tilendor..:

我从这两个网站找到了答案:Net Maniac和Aimred.

你需要有版本> 0.8的rake来使用这种技术

正常的rake任务描述如下:

desc 'Task Description'
task :task_name => [:depends_on_taskA, :depends_on_taskB] do
  #interesting things
end

要传递参数,请执行以下三项操作:

    在任务名称后添加参数名称,以逗号分隔.

    使用:needs => [...]将依赖项放在最后

    放置| t,args | 做完之后.(t是此任务的对象)

要访问脚本中的参数,请使用args.arg_name

desc 'Takes arguments task'
task :task_name, :display_value, :display_times, :needs => [:depends_on_taskA, :depends_on_taskB] do |t, args|
  args.display_times.to_i.times do
    puts args.display_value
  end
end

要从命令行调用此任务,请将参数传递给[] s

rake task_name['Hello',4]

将输出

Hello
Hello
Hello
Hello

如果要从另一个任务调用此任务,并传递参数,请使用invoke

task :caller do
  puts 'In Caller'
  Rake::Task[:task_name].invoke('hi',2)
end

那么命令

rake caller

将输出

In Caller
hi
hi

我没有找到一种方法来传递参数作为依赖项的一部分,因为以下代码中断:

task :caller => :task_name['hi',2]' do
   puts 'In Caller'
end


此功能的格式已更改,因为此警告指出:''task:t,arg,:needs => [deps]'已弃用.请改用'task:t,[args] => [deps]'

6> kch..:

另一个常用选项是传递环境变量.在您的代码中,您ENV['VAR']可以通过它读取它们,并且可以在rake命令之前传递它们,例如

$ VAR=foo rake mytask


@jhs:`rake blah - --these --go --to --a-program`(注意` - `告诉rake它的开关已经结束),见http://stackoverflow.com/questions/5086224 /何灿I-传递命名参数对A-耙任务/ 5086648#5086648

7> fl00r..:

实际上@Nick Desjardins回答得很完美.但仅仅是为了教育:你可以使用肮脏的方法:使用ENV参数

task :my_task do
  myvar = ENV['myvar']
  puts "myvar: #{myvar}"
end 

rake my_task myvar=10
#=> myvar: 10



8> Nate Flink..:

我无法弄清楚如何传递args以及:环境,直到我解决了这个问题:

namespace :db do
  desc 'Export product data'
  task :export, [:file_token, :file_path] => :environment do |t, args|
    args.with_defaults(:file_token => "products", :file_path => "./lib/data/")

       #do stuff [...]

  end
end

然后我这样打电话:

rake db:export['foo, /tmp/']



9> Feng..:
desc 'an updated version'
task :task_name, [:arg1, :arg2] => [:dependency1, :dependency2] do |t, args|
    puts args[:arg1]
end


来自http://rake.rubyforge.org/files/doc/rakefile_rdoc.html"只需提几句注意事项.rake任务名称及其参数需要是rake的单个命令行参数.这通常意味着没有空格.如果需要空格,则应引用整个rake +参数字符串.如下所示:rake"name [billy bob,smith]""

10> jassa..:

我只是希望能够运行:

$ rake some:task arg1 arg2

简单吧?(不!)

Rake解释arg1arg2作为任务,并尝试运行它们.所以我们只是在它之前中止.

namespace :some do
  task task: :environment do
    arg1, arg2 = ARGV

    # your task...

    exit
  end
end

拿那个,括号!

免责声明:我希望能够在一个非常小的宠物项目中做到这一点.不适合"现实世界"使用,因为您失去了链接rake任务的能力(即rake task1 task2 task3).IMO不值得.只是用丑陋的rake task[arg1,arg2].


需要使这个`_,arg1,arg2 = ARGV`作为第一个arg被认为是rake任务的名称.但那个"退出"是一个巧妙的伎俩.

11> djburdick..:

我在rake文件中使用常规ruby参数:

DB = ARGV[1]

然后我将文件底部的rake任务存根(因为rake将根据该参数名称查找任务).

task :database_name1
task :database_name2

命令行:

rake mytask db_name

这对我来说比var = foo ENV var和任务args [blah,blah2]解决方案感觉更干净.
如果您只有一些一次性设置的环境,那么存根有点粗糙,但也不会太糟糕


要防止冻结字符串问题,请在末尾使用`dup`:db = ARGV [1] .dup

12> Asim Mushtaq..:

在上面的答案中,传递参数的方法是正确的.但是,要使用参数运行rake任务,较新版本的rails会涉及一个小技术问题

它将与rake"namespace:taskname ['argument1']"一起使用

请注意从命令行运行任务时的反向引号.

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有