質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

2回答

1665閲覧

cronの定期実行が思ったように動かない

manami0419

総合スコア10

cron

cronは、Unix系OS上でデーモンプロセスとして動作する、スクリプトの自動実行が可能なジョブスケジューラです。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/02/03 13:36

編集2021/02/04 14:16

前提・実現したいこと

TwitterのDMを定期的に送りたいと考えています。
そのためにcronを使って定期実行を行っているのですが、うまくいきません。

ただ、単発実行ではうまくいっているので、その原因を教えていただきたいです。
よろしくお願いいたします。

発生している問題・エラーメッセージ

cronの単発実行はうまくいくが、定期実行はうまくいかない。
そもそもこのツールの仕様は、
①保存されている内容(アカウント名、文章)でDMを送る。
②送ることができたできないに関係なく、その後すぐその情報はDBから消去される
というものです。

単発実行ではこれらが正常に作動します。
しかし定期実行になると、①はうまく実行されず、②だけ実行されます。

該当のソースコード

run_regularly.rake

namespace :minite_post do desc "保存内容を一件ずつ送信" task :regularly_flag => :environment do #ログ logger = Logger.new 'log/run_regularly.log' #ここから処理を書いていく @client = Twitter::REST::Client.new do |config| config.consumer_key = ENV["TWITTER_CONSUMER_KEY"] config.consumer_secret = ENV["CONSUMER_SECRET"] config.access_token = ENV["ACCESS_TOKEN"] config.access_token_secret = ENV["ACCESS_TOKEN_SECRET"] end @user_num = SendInfo.count @user = SendInfo.first begin @client.create_direct_message(@client.user(@user.name).id, "#{@client.user(@user.name).name}#{@user.atena}\n\n#{@user.text}") rescue => error puts error     puts config.access_token_secret ←追加 end if @user_num >= 1 @user.destroy end #デバッグのため p "OK" end end

  
ログ(run_regularly.rakeに「puts config.access_token_secret」を追加した際)

Invalid or expired token. rake aborted! NameError: undefined local variable or method `config' for main:Object /Users/yuta/projects/AutoTwitterDM/lib/tasks/run_regularly.rake:20:in `rescue in block (2 levels) in <main>' /Users/yuta/projects/AutoTwitterDM/lib/tasks/run_regularly.rake:16:in `block (2 levels) in <main>' /Users/yuta/.rbenv/versions/2.6.5/bin/bundle:23:in `load' /Users/yuta/.rbenv/versions/2.6.5/bin/bundle:23:in `<main>' Caused by: Twitter::Error::Unauthorized: Invalid or expired token. /Users/yuta/projects/AutoTwitterDM/lib/tasks/run_regularly.rake:17:in `block (2 levels) in <main>' /Users/yuta/.rbenv/versions/2.6.5/bin/bundle:23:in `load' /Users/yuta/.rbenv/versions/2.6.5/bin/bundle:23:in `<main>' Tasks: TOP => minite_post:regularly_flag (See full trace by running task with --trace)

  
schedule.rb

# Rails.rootを使用するために必要。なぜなら、wheneverは読み込まれるときにrailsを起動する必要がある require File.expand_path(File.dirname(__FILE__) + "/environment") # cronを実行する環境変数 rails_env = ENV['RAILS_ENV'] || :development # cronを実行する環境変数をセット set :environment, rails_env # cronのログの吐き出し場所。ここでエラー内容を確認する set :output, "#{Rails.root}/log/cron.log" every 1.minutes do rake "minite_post:regularly_flag" end

  
cronへの登録情報

* * * * * /bin/bash -l -c 'cd /Users/manami/projects/AutoTwitterDM && RAILS_ENV=development bundle exec rake minite_post:regularly_flag --silent >> /Users/manami/projects/AutoTwitterDM/log/cron.log 2>&1'

  
rescueのログ(単発実行時)
ただし、DM送信はできている。

undefined method `name' for nil:NilClass "OK"

  
rescueのログ(定期実行時)
DM送信はできない。

Invalid or expired token. "OK"

  

puts config.access_token_secret

補足情報(FW/ツールのバージョンなど)

ruby 2.6.5p114
Rails 6.0.3.4

参考にさせていただいたサイト
定期実行する rake taskとcronの使い方

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t_obara

2021/02/03 15:10

ログなど出力して確認してみてはいかがでしょうか?
Daregada

2021/02/04 01:30

問題になっているのは、「cronでの動作」なのですから、「単発実行」と「定期実行」と書くのではなく、それぞれ「実際にどのようにcronに登録しているか」を質問文に書いてください。
manami0419

2021/02/04 01:50

t_obara様 ご指摘ありがとうございます。 定期実行時と単発実行時に分けてログを出力してみました。 特にエラーは出ていないのですが、どうでしょうか?
manami0419

2021/02/04 02:01

Daregada様 ご指摘ありがとうございます。 それぞれ上記に追加した情報がcronに登録されています。 初心者で申し訳ございませんが、よろしくお願いいたします。
guest

回答2

0

自己解決

シェルに保存していたAPIのトークンに相違があったためエラーが起きていました。
これからトークンを保存するときは、Envに保存していきます。
コメントしていただいた方、誠にありがとうございました。

投稿2021/02/11 13:25

manami0419

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

単発実行 とは cron を通さずに「cronで記述したコマンドを実行」ですね?
これが動き、cronでは動かないのはPATHの違いが影響していることが多いです。

コマンド自体が見つからないだけでしたら full path で記述すればよいですが、コマンドの内部でもpathが通っていないとだめな場合は「cron のPATH」あたりで検索すると沢山出てくると思います。

追記
cronだと動かないというのに条件反射してしまい PATH だろうと思ったのですが、載せていただいた logをみると実行はしているので、PATHではないですね。
@client.create_direct_message の失敗が原因だとおもわれます。
単発とcronでなにがの環境のちがいが出ているのでしょう。
どんな例外が出ているのか確認しましょう。
rescueの中で エラーメッセージを logにだしてみてください

追記2
access_token_secret などを環境変数から得ていますが、この環境変数はどこで定義していますか

投稿2021/02/03 23:26

編集2021/02/04 11:28
winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

manami0419

2021/02/04 05:45

ご回答ありがとうございます。 full pathの記述ですが、どこに書けばよろしいですか? 初心者でわからず、申し訳ありませんがよろしくお願いいたします。
manami0419

2021/02/04 08:46

上記のように、run_regularly.rakeのrescueの中を修正いたしました。 しかしログを見ても変わりはありませんでした。 記述の仕方が間違えていると思うのですが、どうでしょうか?
manami0419

2021/02/04 09:12

すみません、違うlogを見ていました。 そこにエラーで、「Invalid or expired token.」と出ていたので、一度トークンを更新してみます。
winterboum

2021/02/04 09:12

cronだと動かないというのに条件反射してしまい PATH だろうと思ったのですが、載せていただいた logをみると実行はしているので、PATHではないですね。 `@client.create_direct_message` の失敗が原因だとおもわれます。 単発とcronでなにがの環境のちがいが出ているのでしょう。 どんな例外が出ているのか確認しましょう。 rescueの中で エラーメッセージを logにだしてみてください
manami0419

2021/02/04 09:39

rescueのログ、確認いたしました。 上記に追加・修正しています。 定期実行時のrescueのログに関して、上記のように「Invalid or expired token.」が出ていたのでトークンを更新しましたが、同じ結果になりました。
manami0419

2021/02/04 11:38

環境変数はzshに定義しています。
winterboum

2021/02/04 11:39

「zshに定義」とは具体的にはどのfileに書いてます?
manami0419

2021/02/04 11:54

どのファイルなのかはわからないのですが、ターミナルで「vim ~/.zshrc」を実行し、その中に記述してあります。
winterboum

2021/02/04 12:26

ああ、それだと私の回答の一番最初に書いたPATHと同じ運命で、取り込まれていません。 「cron 環境変数」で検索すると色々出てきますが、railsなので、 gem Dotenvを使うのが良いかな。 例えば https://qiita.com/ryosuketter/items/ceb592dc6b23a20e51b5 を参考に。
manami0419

2021/02/04 13:11

たびたび申し訳ありません。 ご教示いただいたサイトのように.envのファイルを作成しましたが、結果は変わらず「Invalid or expired token.」が出てきてしまいます。irbでも環境変数がちゃんと登録してあるか確認しております。 他に何か原因があるのでしょうか?
manami0419

2021/02/04 13:20

今気付いたのですが、 schedule.rbの ENV['RAILS_ENV']が nilになっていたのですが、これはこれで大丈夫なのでしょうか? 大丈夫がなければ、何を入れなければいけないのでしょうか? よろしくお願いいたします。
winterboum

2021/02/04 14:02

gem を入れて bundle install はしましたか? もしそうであってもおかしいなら 環境変数が取れているか logに出してみてください。 ENV['RAILS_ENV']が nil ??  cronへのcommandで RAILS_ENV=development bundle exec なのに??
manami0419

2021/02/04 14:24

bundle installもしてサーバーも再起動させています。 環境変数のlogの出し方ですが、上記に追加した方法(run_regularly.rake)であっていますでしょうか? またその方法でlogを出した場合、run_regularly.rakeの下にあるようなlogが出ました。 irbでENV['RAILS_ENV']を打つと、nilが返ってきてしまいます。
winterboum

2021/02/04 22:39 編集

いや、crontabに書いてあるcommandを打ってください。 run_regularly.rake だと環境変数設定しないで起動してますから nilです。 ただ、その場合はdevelopmentに設定されるから動きますが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問