980

여러 개의 데이터베이스에 값을 삽입해야하는 레이크 작업이 있습니다.

이 값을 커맨드 라인에서 rake 태스크로 전달하고 싶습니다.다른레이크 작업.

어떻게해야합니까?


  • rakefile rdoc - Brian Maltzan
  • 문서 도구SeattleRb에 의해 반영되었습니다. - Jonathan Allard
  • @BlairAnderson의 답변을 수락 해 주실 수 있습니까? 지금은 받아 들여진 답변이 매우 오래되었습니다. 이 질문은이 주제에 대해 Google에서 높은 것으로 나타납니다. - rmcsharry

17 답변


264

옵션 및 종속성은 배열 내부에 있어야합니다.

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"}

참고 : 변수taskRake 내부에 대해 잘 모르거나 신경 쓰지 않으면 태스크 오브젝트입니다.

RAILS NOTE :

작업을 레일에서 실행하는 경우 환경을 미리로드하는 것이 좋습니다.=> [:environment]이것이 설치 방법입니다.매달린작업.

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


  • 이 작업은 2016 년 8 월에 작동했습니다 ... 업데이트 된 답변은 내가 생각하기에 업데이트해야합니다! - rmcsharry
  • 요청에 의해 대답으로 받아 들여 지도록 업데이트했습니다. 그러나 태스크 자체에서 다른 레이크 태스크에 인수를 전달하는 방법을 설명하지는 않습니다. - Tilendor
  • 또한 인수 사이에 공백을 사용하지 않아야합니다. 예 : 이렇게하지 마세요.rake thing:work[1, 2, 3]작동하지 않아 오류가 발생합니다.Don't know how to build task - rpbaltazar
  • 또한 인수를 문자열로 묶어야합니다. 예 : 커맨드 라인에서 rake 태스크를 실행하십시오.rake thing:work'[1,2,3]' - Damian Simon Peter
  • 유감스럽게도, zsh는 호출을 정확하게 구문 분석 할 수 없으므로 다음과 같이 zsh에 명령을 입력해야합니다.rake thing:work\[1,2,3\], 아니면 이거rake 'thing:work[1,2,3]' - hutusi

1093

타스크 인수에 기호 인수를 추가하여 레이크에서 형식 인수를 지정할 수 있습니다. 예 :

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"}

두 번째 예에서 설명한 것처럼 공백을 사용하려면 쉘이 공백에서 인수를 분할하지 못하도록 대상 이름 주위의 따옴표가 필요합니다.

에서 코드를보고rake.rb, 레이크가 전제 조건에 대한 인수를 추출하기 위해 작업 문자열을 구문 분석하지 않으므로 수행 할 수 없습니다.task :t1 => "dep[1,2]". 전제 조건에 대해 다른 인수를 지정하는 유일한 f}은 종속 타스크 조치에서 명시 적으로 호출하는 것입니다.:invoke_my_task:invoke_my_task_2.

일부 쉘 (zsh과 같은)은 대괄호를 이스케이프 처리해야합니다.rake my_task\['arg1'\]


  • 네임 스페이스 내에서 작업을 호출하려면 simpy : Rake :: Task [네임 스페이스 : 작업]. invoke - gaqzi
  • 그것은 Igoru와는 별도의 질문이지만, 호출하는 호출이 한 번만 실행되는 이유는 레이크가 종속성 지향적이므로, 필요할 경우에만 태스크를 실행합니다. 이미 실행되지 않은 일반적인 작업의 경우 종속성에 관계없이 작업을 명시 적으로 실행하거나 필요한 경우 invoke 대신 execute를 호출하십시오. - Nick Desjardins
  • 참고 : rake에 따르면, 태스크에서 변수를 받아들이는이 구문은 더 이상 사용되지 않습니다.WARNING: 'task :t, arg, :needs => [deps]' is deprecated. Please use 'task :t, [args] => [deps]' instead. - Ajedi32
  • zsh는 명령 행 인수를 올바르게 구문 분석하지 못합니다 (zsh: no matches found: ...), 그래서 당신은 대괄호를 탈출해야합니다 :rake my_task\['arg1'\]. 에서robots.thoughtbot.com/post/18129303042/… - Seth Bro
  • @SethBro 예. & quot; 더 많은 댓글보기 & quot; 뒤에 댓글 만 숨겨져 있지 않은 경우 링크 나는이 일을 할 수없는 10 분을 낭비하지 않았다. - GMA

303

kch 님의 답변 외에도 (나는 그것에 주석을 남길 수있는 방법을 찾지 못했습니다.)

변수를 지정할 필요가 없습니다.ENV변수 앞에rake명령. 다음과 같은 일반적인 명령 줄 매개 변수로 설정할 수 있습니다.

rake mytask var=foo

레이크 파일에서 ENV 변수로 액세스 할 수 있습니다.

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


  • 정말 편리합니다. 감사! - Hoang Le
  • 아, 그래.Rails가 어떻게하는지입니다. 말이된다... - Ajedi32

99

명명 된 인수를 전달하려는 경우 (예 : 표준OptionParser) 다음과 같이 사용할 수 있습니다.

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

주의하다--이는 표준 레이크 인수를 우회하는 데 필요합니다. 레이크와 협력해야한다.0.9.x,10.3.x.

최신 갈퀴가 파싱을 변경했습니다.--, 이제는 그것이 전달되지 않았는지 확인해야합니다.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 user:create -- -u test@example.com -p 123

갈퀴 스크립트가 이와 같이 보일 때, 아마도 상자 밖에서 이것을 허용 할 다른 도구를 찾아야 할 때입니다.


  • 내 관점에서 볼 때 이것이 가장 좋은 대답입니다. 환경 변수 kludges 무시, 작업 인수가있는 이상한 구문, 표준에 대한 추가 이점--option-names. 내 유일한 제안은exit오히려abort같이abort쉘에 리턴 코드 1을 남기게됩니다. 레이크 작업이 상위 레벨 스크립트의 일부인 경우 0이 아닌 종료라고 가정하는 것이 더 일반적입니다. 오류 유형입니다. - Joe
  • 나는 Joe와 동의합니다. 이것이 최고의 대답입니다. 자연스러운 것은 옵션을 스크립트에 전달할 때와 마찬가지로 레이크에 옵션을 전달하기 위해 동일한 인터페이스를 사용하는 것입니다. - Rik Smith-Unna
  • 나는 이것이 최선의 대답이라는 데 동의한다. 추한 곳을 우회하는 방법이 없어야합니다.--? 지나가는 것rake실제 과제 나 다른 것에 대한 논증? 처럼task :my_task, :*args do |t, args|또는 뭔가? - Augustin Riedinger
  • 게다가, 나는 무엇을 이해하지 못한다.{username}여기에 있습니다. 사용 장소는 어디입니까? 왜 거기에 있지 않는가?-u {username}? 건배 - Augustin Riedinger
  • 레이크가 ARGV를 분석하는 방법은 다음과 같이 변경되었습니다.10.4.1안으로 되돌아왔다.10.4.2.github.com/ruby/rake/commit/… - Tombart

56

나는이 두 웹 사이트에서 답을 찾았습니다.순 매니아Aimred.

이 기법을 사용하려면 레이크 버전이 0.8 이상이어야합니다.

정상적인 레이크 작업 설명은 다음과 같습니다.

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

인수를 전달하려면 다음 세 가지를 수행하십시오.

  1. 인수 이름을 쉼표로 구분하여 태스크 이름 다음에 추가하십시오.
  2. 필요에 따라 종속성을 넣으십시오 : needs => [...]
  3. 장소 | 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

명령 줄에서이 작업을 호출하려면 [] 안에 인수를 전달하십시오.

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]' is deprecated. Please use 'task :t, [args] => [deps]' instead. - madh

30

일반적으로 사용되는 또 다른 옵션은 환경 변수를 전달하는 것입니다. 코드에서 다음을 통해 읽습니다.ENV['VAR'], 그리고 그것들을 바로 앞에 전달할 수 있습니다.rake명령처럼

$ VAR=foo rake mytask


  • 솔직히 나는 갈퀴 작업을 기대하고 있었다. --go --to - a 프로그램과 나의 작업은 ARGV에서 그들을 얻을 수 있었다. 불행히도 현재 가능한 해결책인지 잘 모릅니다. rake var1 = val1 var2 = val2 - JasonSmith
  • @jhs :rake blah -- --these --go --to --a-program(--레이크에게 스위치가 종료되었음을 알리기 위해)stackoverflow.com/questions/5086224/… - mu is too short

30

실제로 @Nick Desjardins는 완벽하다고 대답했습니다. 하지만 교육 만하면 더러운 접근 방식을 사용할 수 있습니다.ENV논의

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

rake my_task myvar=10
#=> myvar: 10


24

나는이 문제를 해결할 때까지 args와 : environment를 전달하는 방법을 알 수 없었다.

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/']


23

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


  • 이것을 부르려면 다음으로 가십시오 :rake task_name[hello, world] - Dex
  • ...에서rake.rubyforge.org/files/doc/rakefile_rdoc.html& quot; 조심스런 단어입니다. rake 작업 이름과 인수는 rake에 대한 단일 명령 줄 인수 여야합니다. 이것은 일반적으로 공백이 없음을 의미합니다. 공백이 필요한 경우 전체 레이크 + 인수 문자열을 따옴표로 묶어야합니다. 이런 것 : rake & quot; name [빌리 보브, 스미스] & quot; & quot; - Gayle

16

나는 지금 막 달릴 수 있고 싶었다 :

$ rake some:task arg1 arg2

간단 하죠? (아니!)

갈퀴 통역arg1arg2작업으로 간주하고 실행하려고 시도합니다. 그래서 우리는 단지 그것을하기 전에 중단합니다.

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

    # your task...

    exit
  end
end

가져 가라.

기권: 나는 아주 작은 애완 동물 프로젝트에서 이것을 할 수 있기를 원했습니다. 레이크 작업을 체인화 할 수 없기 때문에 "실제"사용을 목적으로하지 않습니다 (예 :rake task1 task2 task3). 그만한 가치가없는 IMO. 추악한 것을 사용하십시오.rake task[arg1,arg2].


  • 이것을 만들기 위해 필요했다._, arg1, arg2 = ARGV첫 번째 논의가 레이크 과제의 이름으로 보였던 것처럼 하지만 그건exit깔끔한 트릭입니다. - fatty
  • rake task[arg1,arg2] && rake task2 && rake task3그보다 덜 못생긴 것인지 잘 모르겠다.rake task[arg1,arg2] task2 task3. 아마 덜 효율적인. - Nuclearman
  • _, *args = ARGV모든 후속 인수를 포착하기에 완벽합니다! 감사합니다. - XtraSimplicity

13

레이크 파일에서 일반적인 루비 인수를 사용합니다.

DB = ARGV[1]

파일의 맨 아래에있는 레이크 작업을 스텁 아웃합니다 (레이크가 해당 인수 이름을 기반으로 작업을 찾을 것이기 때문에).

task :database_name1
task :database_name2

명령 줄 :

rake mytask db_name

이것은 var = foo ENV var 및 task args [blah, blah2] 솔루션보다 나에게 더 깔끔하게 느껴집니다.

그루터기는 조금 엉성합니다. 단 한 번의 설정으로 몇 가지 환경 만 있다면 너무 나쁘지 않습니다.


  • 고정 된 문자열 문제를 방지하려면dup끝에 : db = ARGV [1] .dup - Juanda
  • 더 나은 행사db = ARGV[1].dup unless ARGV[1].nil?duping a nil의 예외를 방지합니다. - Andre Figueiredo

5

인수를 전달하는 방법은 위의 대답에서 정확합니다. 그러나 인수를 사용하여 레이크 작업을 실행하려면 새로운 버전의 레일에 관련된 작은 기술적 인 문제가 있습니다.

rake "네임 스페이스와 함께 작동합니다 : taskname [ 'argument1']"

명령 행에서 태스크를 실행할 때 거꾸로 된 따옴표를 주목하십시오.


4

필자는 인수 전달을위한 "쿼리 문자열"구문을 좋아하는데 특히 인수가 많은 경우에 유용합니다.

예:

rake "mytask[width=10&height=20]"

"querystring"존재 :

width=10&height=20

경고:구문은 다음과 같습니다.rake "mytask[foo=bar]"아니 rake mytask["foo=bar"]

갈퀴 작업 내에서 파싱 할 때Rack::Utils.parse_nested_query, 우리는Hash:

=> {"width"=>"10", "height"=>"20"}

(멋진 점은 해시와 배열을 전달할 수 있다는 것입니다.

이것은 이것을 달성하는 방법입니다 :

require 'rack/utils'

task :mytask, :args_expr do |t,args|
  args.with_defaults(:args_expr => "width=10&height=10")
  options = Rack::Utils.parse_nested_query(args[:args_expr])
end

다음은 레일즈에서 사용하고있는 확장 된 예제입니다.delayed_job_active_record_threaded보석:

bundle exec rake "dj:start[ebooks[workers_number]=16&ebooks[worker_timeout]=60&albums[workers_number]=32&albums[worker_timeout]=120]"

위와 같은 방식으로 환경 의존성을 파싱했다 (Rails 환경을로드하기 위해)

namespace :dj do
  task :start, [ :args_expr ] => :environment do |t, args|
    # defaults here...
    options = Rack::Utils.parse_nested_query(args[:args_expr])  
  end
end

다음을 제공합니다.options

=> {"ebooks"=>{"workers_number"=>"16", "worker_timeout"=>"60"}, "albums"=>{"workers_number"=>"32", "worker_timeout"=>"120"}}


  • Downvoter, 정교한 신경? - Abdo

3

기본 작업에 인수를 전달하려면 다음과 같이하면됩니다. 예를 들어, 다음과 같이 말하십시오. "버전"은 귀하의 주장입니다 :

task :default, [:version] => [:build]

task :build, :version do |t,args|
  version = args[:version]
  puts version ? "version is #{version}" : "no version passed"
end

그럼 당신은 그렇게 부를 수 있습니다 :

$ rake
no version passed

또는

$ rake default[3.2.1]
version is 3.2.1

또는

$ rake build[3.2.1]
version is 3.2.1

그러나 인수를 전달하는 동안 작업 이름 (기본 또는 빌드)을 지정하지 않도록하는 방법을 찾지 못했습니다. 아무도 모른다면 듣고 싶습니다.


2

위에서 설명한 대부분의 방법은 저에게 효과적이지 않았습니다. 새 버전에서는 더 이상 사용되지 않을 수도 있습니다. 최신 안내서는 다음에서 찾을 수 있습니다.http://guides.rubyonrails.org/command_line.html#custom-rake-tasks

가이드에서 복사하여 붙여 넣기 ans 여기에 있습니다 :

task :task_name, [:arg_1] => [:pre_1, :pre_2] do |t, args|
  # You can use args from here
end

이런 식으로 불러내 라.

bin/rake "task_name[value 1]" # entire argument string should be quoted


2

만약 당신이 어떤 인수 위치가 무엇인지를 기억하지 못한다면, 루비 인자 해쉬와 같은 일을하고 싶을 것입니다. 하나의 인수를 사용하여 문자열을 전달한 다음 해당 문자열을 옵션 해시로 정규 표현할 수 있습니다.

namespace :dummy_data do
  desc "Tests options hash like arguments"
  task :test, [:options] => :environment do |t, args|
    arg_options = args[:options] || '' # nil catch incase no options are provided
    two_d_array = arg_options.scan(/\W*(\w*): (\w*)\W*/)
    puts two_d_array.to_s + ' # options are regexed into a 2d array'
    string_key_hash = two_d_array.to_h
    puts string_key_hash.to_s + ' # options are in a hash with keys as strings'
    options = two_d_array.map {|p| [p[0].to_sym, p[1]]}.to_h
    puts options.to_s + ' # options are in a hash with symbols'
    default_options = {users: '50', friends: '25', colour: 'red', name: 'tom'}
    options = default_options.merge(options)
    puts options.to_s + ' # default option values are merged into options'
  end
end

커맨드 라인에서 얻을 수 있습니다.

$ rake dummy_data:test["users: 100 friends: 50 colour: red"]
[["users", "100"], ["friends", "50"], ["colour", "red"]] # options are regexed into a 2d array
{"users"=>"100", "friends"=>"50", "colour"=>"red"} # options are in a hash with keys as strings
{:users=>"100", :friends=>"50", :colour=>"red"} # options are in a hash with symbols
{:users=>"100", :friends=>"50", :colour=>"red", :name=>"tom"} # default option values are merged into options


  • 코드에는 몇 개의 잘 배치 된 빈 줄이 필요합니다. 그 글을 읽는 방법을 모르겠다. - Joshua Pinter

-5

매개 변수를 전달하는 동안 더 나은 옵션은 입력 파일입니다.이 옵션은 json 또는 기타 필요한 것보다 뛰어날 수 있으며 필요에 따라 변수 이름을 포함하여 필요한 데이터 구조와 변수를 읽을 수 있습니다. 파일을 읽으려면 다음과 같은 구조를 가질 수 있습니다.

  namespace :name_sapace_task do
    desc "Description task...."
      task :name_task  => :environment do
        data =  ActiveSupport::JSON.decode(File.read(Rails.root+"public/file.json")) if defined?(data)
    # and work whit yoour data, example is data["user_id"]

    end
  end

예 json

{
  "name_task": "I'm a task",
  "user_id": 389,
  "users_assigned": [389,672,524],
  "task_id": 3
}

실행

rake :name_task 


  • Rake 작업을위한 JSON 명령어 파일이 필요하다면, Rake 작업에서 너무 많은 일을하고있을 것이다. - ZiggyTheHamster
  • 이것은방법믿을 수 없을만큼 단순한 것을 지나치게 복잡하게 만든다. - jeffdill2

연결된 질문


관련된 질문

최근 질문