从crontab运行rake任务

时间:2019-01-04 22:19:35

标签: ruby-on-rails cron ruby-on-rails-5 ubuntu-18.04 rake-task

我遇到了一个我无法想象的解决方案的问题,并且让我呆了一个星期。我在sudo crontab -e中有以下两行。

* * * * * echo "crontab can log to reports" >> /var/log/mazer-reports.log
* * * * * /bin/bash -l -c 'cd /home/deploy/shopify_pull_and_store && /home/deploy/.rbenv/shims/bundle exec rake run_split_accounting_after_close_master >> /var/log/mazer-reports.log'

大约10分钟后,我的'mazer-reports.log'如下所示:

crontab can log to reports
crontab can log to reports
crontab can log to reports
crontab can log to reports
crontab can log to reports
crontab can log to reports
crontab can log to reports
crontab can log to reports
crontab can log to reports
crontab can log to reports
crontab can log to reports

因此,第一个命令正在触发,并且可以正常记录。但是,第二个命令既不记录日志,也不触发适当的rake任务(该任务的效果在我的Rails应用程序中看不到)。此外,我知道该命令没有任何问题,因为如果我只是接受命令本身并在控制台中运行它:

/bin/bash -l -c 'cd /home/deploy/shopify_pull_and_store && /home/deploy/.rbenv/shims/bundle exec rake run_split_accounting_after_close_master >> /var/log/mazer-reports.log'

然后我将以下内容附加到我的'mazer-reports.log'中,这是正确的:

   (0.8ms)  SELECT MAX("delayed_jobs"."priority") FROM "delayed_jobs" WHERE "delayed_jobs"."queue" = $1  [["queue", "RunReports"]]
   [ActiveJob]    (0.1ms)  BEGIN
   [ActiveJob]   SQL (0.4ms)  INSERT INTO "delayed_jobs" ("handler", "run_at", "queue", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  
   [["handler", "--- !ruby/object:ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper\njob_data:\n  job_class: RunReportsSplitMasterJob\n  job_id: 79333d26-4917-4226-8d86-8fef481c86d0\n  provider_job_id: \n  queue_name: RunReports\n  priority: \n  arguments: []\n  executions: 0\n  locale: en\n"], ["run_at", "2019-01-04 22:06:35.189280"], ["queue", "RunReports"], ["created_at", "2019-01-04 22:06:35.189369"], ["updated_at", "2019-01-04 22:06:35.189369"]]
   [ActiveJob]    (0.5ms)  COMMIT
   [ActiveJob] Enqueued RunReportsSplitMasterJob (Job ID: 79333d26-4917-4226-8d86-8fef481c86d0) to DelayedJob(RunReports)

我也可以看到在Rails应用程序上触发任务的效果,在crontab中看不到它,因此这不仅仅是记录问题。 crontab根本不喜欢该命令。这是sudo grep CRON /var/log/syslog的输出:

Jan  4 22:12:01 shopify-inventory-reports CRON[24417]: (root) CMD (echo "crontab can log to reports" >> /var/log/mazer-reports.log)
Jan  4 22:12:03 shopify-inventory-reports CRON[24415]: (CRON) info (No MTA installed, discarding output)
Jan  4 22:13:01 shopify-inventory-reports CRON[24453]: (root) CMD (/bin/bash -l -c 'cd /home/deploy/shopify_pull_and_store && /home/deploy/.rbenv/shims/bundle exec rake run_split_accounting_after_close_master >> /var/log/mazer-reports.log')
Jan  4 22:13:01 shopify-inventory-reports CRON[24454]: (root) CMD (echo "crontab can log to reports" >> /var/log/mazer-reports.log)
Jan  4 22:13:03 shopify-inventory-reports CRON[24452]: (CRON) info (No MTA installed, discarding output)
Jan  4 22:14:01 shopify-inventory-reports CRON[24490]: (root) CMD (/bin/bash -l -c 'cd /home/deploy/shopify_pull_and_store && /home/deploy/.rbenv/shims/bundle exec rake run_split_accounting_after_close_master >> /var/log/mazer-reports.log')
Jan  4 22:14:01 shopify-inventory-reports CRON[24491]: (root) CMD (echo "crontab can log to reports" >> /var/log/mazer-reports.log)
Jan  4 22:14:04 shopify-inventory-reports CRON[24489]: (CRON) info (No MTA installed, discarding output)
Jan  4 22:15:01 shopify-inventory-reports CRON[24528]: (root) CMD (/bin/bash -l -c 'cd /home/deploy/shopify_pull_and_store && /home/deploy/.rbenv/shims/bundle exec rake run_split_accounting_after_close_master >> /var/log/mazer-reports.log')

您可以从那里看到cron每分钟都在运行这两个命令(应该这样做),并且没有在该命令上向系统日志发布错误,而该错误似乎什么也没做。十分令人困惑!

我正在Ubuntu 18安装上运行rails 5,puma和rbenv。所有这些东西都安装在名为deploy的sudoer用户上。以下是ls -l /var/log/mazer-reports.log的输出:

-rw-rw-rw- 1 root root 1543 Jan  4 22:10 mazer-reports.log

更新1/6/2018 Romeo Ninov在评论中指出,我应该考虑shell与cronjob的环境变量。当然,* * * * * /bin/bash -l -c 'echo $RAILS_ENV' >> /var/log/mazer-reports.log的输出为空,这意味着rake在需要生产时不知道从crontab运行哪个rails环境。为了解决这个问题,我将环境变量放在crontab中的命令本身中,如下所示:

 0 * * * * cd /home/deploy/shopify_pull_and_store && /home/deploy/.rbenv/shims/bundle exec rake RAILS_ENV=production run_split_accounting_after_close_master >> /var/log/mazer-reports.log`

但是,这仍然不能解决问题。命令仍然没有触发,也没有记录到指定的日志文件。我没有在考虑其他一些必要的耙环境变量? Systemd已经在使用应用程序密钥和数据库用户及密码运行puma。我从没想过耙会需要这样的东西,但是告诉我我是否错


更新1/7/2018 好的,显然这是一个环境变量问题。我已经创建了一个单独的bash文件,称为“ run_accounting”,如罗密欧的答案所述:

#!/bin/bash
source ~/.bashrc
echo "stuff from run_accounting bash" >> /var/log/mazer-reports.log
env >> /var/log/mazer-reports.log
cd /home/deploy/shopify_pull_and_store && /home/deploy/.rbenv/shims/bundle exec rake run_split_accounting_after_close_master >> /var/log/mazer-reports.log

现在,这很奇怪,如果我从终端点击sudo ./run_accounting,将触发rake任务,并且在mazer-reports.log中得到以下输出:

stuff from run_accounting bash
SHELL=/bin/bash
TERM=xterm-256color
USER=root
SUDO_USER=deploy
SUDO_UID=1000
USERNAME=root
RACK_ENV=production
MAIL=/var/mail/root
PATH=/home/deploy/.rbenv/shims:/home/deploy/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
SECRET_KEY_BASE=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PWD=/home/deploy
LANG=en_US.UTF-8
RBENV_SHELL=bash
SHLVL=1
SUDO_COMMAND=./run_accounting
HOME=/home/deploy
RAILS_ENV=production
LOGNAME=root
SHOPIFY_PULL_AND_STORE_DATABASE_USER=shopify_pull_and_store
LESSOPEN=| /usr/bin/lesspipe %s
SHOPIFY_PULL_AND_STORE_DATABASE_PASSWORD=XXXXXXXX
SUDO_GID=1000
LESSCLOSE=/usr/bin/lesspipe %s %s
_=/usr/bin/env
(0.6ms)  SELECT MAX("delayed_jobs"."priority") FROM "delayed_jobs" WHERE "delayed_jobs"."queue" = $1  [["queue", "RunReports"]]
[ActiveJob]    (0.1ms)  BEGIN
[ActiveJob]   SQL (0.9ms)  INSERT INTO "delayed_jobs" ("handler", "run_at", "queue", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  
[["handler", "--- !ruby/object:ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper\njob_data:\n  job_class: RunReportsSplitMasterJob\n  job_id: 7dfd28bd-a47c-475d-9ccf-5a5d8ef756e7\n  provider_job_id: \n  queue_name: RunReports\n  priority: \n  arguments: []\n  executions: 0\n  locale: en\n"], ["run_at", "2019-01-07 18:02:57.355453"], ["queue", "RunReports"], ["created_at", "2019-01-07 18:02:57.355521"], ["updated_at", "2019-01-07 18:02:57.355521"]]
[ActiveJob]    (0.6ms)  COMMIT
[ActiveJob] Enqueued RunReportsSplitMasterJob (Job ID: 7dfd28bd-a47c-475d-9ccf-5a5d8ef756e7) to DelayedJob(RunReports)

但是,在我的crontab中使用* * * * * /home/deploy/run_accounting时,该任务不会触发,并且可以看到所需的环境变量未加载,如下所示:

stuff from run_accounting bash
SHELL=/bin/sh
PATH=/usr/bin:/bin
PWD=/root
LANG=en_US.UTF-8
SHLVL=1
HOME=/root
LOGNAME=root
_=/usr/bin/env

为什么从终端运行bash脚本时bashrc源,而不是从crontab运行相同的命令时为什么?

2 个答案:

答案 0 :(得分:1)

基于您的评论似乎您需要设置环境变量。我将推荐下一种方法:创建将包含您的命令并提供.bashrc文件的shell脚本:

#!/bin/bash
. /home/deploy/.bashrc
# can be also
# . /home/deploy/.bash_profile
cd /home/deploy/shopify_pull_and_store && /home/deploy/.rbenv/shims/bundle exec rake run_split_accounting_after_close_master >> /var/log/mazer-reports.log

您也可以尝试代替.bashrc来获取.bash_profile

然后在cron中运行此Shell脚本。不要忘记使该脚本可执行。

P.S。也许您还需要添加/home/deploy/.bash_profile 通常,从用户的主文件夹(在这种情况下为root)中添加这些文件是明智的。请在/ etc / passwd中签入用户root的住所

答案 1 :(得分:1)

您可以尝试在包执行之前声明环境变量,并使用项目的bin / bundle:

 0 * * * * cd /home/deploy/shopify_pull_and_store && RAILS_ENV=production bin/bundle exec rake run_split_accounting_after_close_master >> /var/log/mazer-reports.log

更新2019-01-07

尝试像这样设置通往.bashrc的路由:

#!/bin/bash
source /home/deploy/.bashrc
echo "stuff from run_accounting bash" >> /var/log/mazer-reports.log
env >> /var/log/mazer-reports.log
cd /home/deploy/shopify_pull_and_store && /home/deploy/.rbenv/shims/bundle exec rake run_split_accounting_after_close_master >> /var/log/mazer-reports.log

或类似这样:

source ~deploy/.bashrc