运行 从 crontab 抽取任务
Running rake tasks from crontab
我 运行 遇到了一个我无法想象解决方案的问题,并且让我陷入了一个星期的困境。我在 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'
这是我的 'mazer-reports.log' 在 10 分钟左右后的样子:
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" = [["queue", "RunReports"]]
[ActiveJob] (0.1ms) BEGIN
[ActiveJob] SQL (0.4ms) INSERT INTO "delayed_jobs" ("handler", "run_at", "queue", "created_at", "updated_at") VALUES (, , , , ) 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 每分钟 运行 执行这两个命令(它应该如此),并且没有在似乎什么都不做的命令上向 syslog 发布错误。相当混乱!
我 运行正在 rails 5、puma 和 rbenv 安装 Ubuntu 18。所有这些东西都安装在一个名为 deploy
的 sudoer 用户上。下面是 ls -l /var/log/mazer-reports.log
:
的输出
-rw-rw-rw- 1 root root 1543 Jan 4 22:10 mazer-reports.log
Update 1/6/2018: Romeo Ninov 在评论中指出我应该考虑 [=74 中的环境变量=] 与定时任务。果然,* * * * * /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`
但是,这仍然没有解决问题。命令仍未触发,也未记录到指定的日志文件。我没有考虑其他一些必要的 rake 环境变量? Systemd 已经 运行ning puma 具有应用程序机密和数据库用户和密码。我从没想过 rake 会需要这样的东西,但如果我错了请告诉我
2018 年 1 月 7 日更新:
好的,很明显这是一个环境变量问题。我创建了一个名为 "run_accounting" 的单独 bash 文件,如 Romeo 的回答中所述:
#!/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:[=28= 中得到以下输出]
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" = [["queue", "RunReports"]]
[ActiveJob] (0.1ms) BEGIN
[ActiveJob] SQL (0.9ms) INSERT INTO "delayed_jobs" ("handler", "run_at", "queue", "created_at", "updated_at") VALUES (, , , , ) 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
为什么 bashrc 在从终端 运行ning 那个 bash 脚本时,但在从 crontab 运行ning 相同的命令时却不是?
根据您的评论,您似乎需要设置环境变量。我将推荐下一种方法:创建 shell 脚本,其中将包含您的命令并获取您的 .bashrc
文件:
#!/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
并且 运行 这个 shell 脚本在 cron 中。不要忘记使此脚本可执行。
P.S。也许您还需要添加 /home/deploy/.bash_profile
一般来说,从用户的主文件夹中添加这些文件是明智的(在本例中为 root
)。请检查 /etc/passwd 用户 root
的家在哪里
您可以尝试在 bundle exec 之前声明环境变量并使用您的项目 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
我 运行 遇到了一个我无法想象解决方案的问题,并且让我陷入了一个星期的困境。我在 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'
这是我的 'mazer-reports.log' 在 10 分钟左右后的样子:
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" = [["queue", "RunReports"]]
[ActiveJob] (0.1ms) BEGIN
[ActiveJob] SQL (0.4ms) INSERT INTO "delayed_jobs" ("handler", "run_at", "queue", "created_at", "updated_at") VALUES (, , , , ) 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 每分钟 运行 执行这两个命令(它应该如此),并且没有在似乎什么都不做的命令上向 syslog 发布错误。相当混乱!
我 运行正在 rails 5、puma 和 rbenv 安装 Ubuntu 18。所有这些东西都安装在一个名为 deploy
的 sudoer 用户上。下面是 ls -l /var/log/mazer-reports.log
:
-rw-rw-rw- 1 root root 1543 Jan 4 22:10 mazer-reports.log
Update 1/6/2018: Romeo Ninov 在评论中指出我应该考虑 [=74 中的环境变量=] 与定时任务。果然,* * * * * /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`
但是,这仍然没有解决问题。命令仍未触发,也未记录到指定的日志文件。我没有考虑其他一些必要的 rake 环境变量? Systemd 已经 运行ning puma 具有应用程序机密和数据库用户和密码。我从没想过 rake 会需要这样的东西,但如果我错了请告诉我
2018 年 1 月 7 日更新: 好的,很明显这是一个环境变量问题。我创建了一个名为 "run_accounting" 的单独 bash 文件,如 Romeo 的回答中所述:
#!/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:[=28= 中得到以下输出]
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" = [["queue", "RunReports"]]
[ActiveJob] (0.1ms) BEGIN
[ActiveJob] SQL (0.9ms) INSERT INTO "delayed_jobs" ("handler", "run_at", "queue", "created_at", "updated_at") VALUES (, , , , ) 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
为什么 bashrc 在从终端 运行ning 那个 bash 脚本时,但在从 crontab 运行ning 相同的命令时却不是?
根据您的评论,您似乎需要设置环境变量。我将推荐下一种方法:创建 shell 脚本,其中将包含您的命令并获取您的 .bashrc
文件:
#!/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
并且 运行 这个 shell 脚本在 cron 中。不要忘记使此脚本可执行。
P.S。也许您还需要添加 /home/deploy/.bash_profile
一般来说,从用户的主文件夹中添加这些文件是明智的(在本例中为 root
)。请检查 /etc/passwd 用户 root
您可以尝试在 bundle exec 之前声明环境变量并使用您的项目 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