web-dev-qa-db-ja.com

Rakeタスク内でコマンドを実行する方法は?

Railsアプリケーションにrakeタスクがあります。rakeタスクでコマンドラインコマンドを実行したいのですが、どうすればよいですか。次の方法で試しましたが失敗します。

desc "Sending the newsletter to all the users"
task :sending_mail do
  run "cd #{Rails_ROOT} && ar_sendmail -o -t NewsLetters -v"
  system "cd #{Rails_ROOT} && ar_sendmail -o -t NewsLetters -v &"
end

上記のrunコマンドはrunmethod undefinedをスローし、Systemコマンドはエラーをスローしませんが実行されません。

19
palani
6
krunal shah

sh Rakeビルトインがおそらく最良の方法です:

task(:sh) do
  sh('echo', 'a')
  sh('false')
  sh('echo', 'b')
end

インターフェースはKernel.systemに似ていますが、次の点に注意してください。

  • 戻り値が!= 0の場合は中止されるため、上記がecho bに達することはありません。
  • コマンド自体は出力の前にエコーされます

runは、コマンドを起動するためにCapistranoやその他のものによって使用されますが、Rakeは代わりにKernel#systemを使用することがよくあります。

コマンドは実行されている可能性がありますが、機能していません。個別にテストできるラッパーシェルスクリプトを作成するか、フルパスを使用して開始してみませんか。

newsletter_script = File.expand_path('ar_sendmail', Rails_ROOT)

if (File.exist?(newsletter_script))
  unless (system(newsletter_script + ' -o -t NewsLetters -v &'))
    STDERR.puts("Script #{newsletter_script} returned error condition")
  end
else
  STDERR.puts("Could not find newsletter sending script #{newsletter_script}")
end

スクリプトがscripts/にないのは奇妙に思えます

system呼び出しは、成功するとtrueを返す必要があります。そうでない場合は、スクリプトがエラーコードを返すか、コマンドを実行できませんでした。

7
tadman