I have a ruby script that connects to an Amazon S3 bucket and downloads the latest production backup. I have tested the script (which is very simple) and it works fine.
我有一个ruby脚本连接到Amazon S3存储桶并下载最新的生产备份。我测试了脚本(非常简单),它工作正常。
However, when I schedule this script to be run as a cron job it seems to fail when it loads the Amazon (aws-s3) gem.
但是,当我将此脚本安排为作为cron作业运行时,它似乎在加载Amazon(aws-s3)gem时失败。
The first few lines of my script looks like this:
我脚本的前几行看起来像这样:
#!/usr/bin/env ruby
require 'aws/s3'
As I said, when I run this script manually, it works fine. When I run it via a scheduled cron job, it fails when it tries to load the gem:
正如我所说,当我手动运行此脚本时,它工作正常。当我通过计划的cron作业运行它时,它在尝试加载gem时失败:
`require': no such file to load -- aws/s3 (LoadError)
`require':没有要加载的文件 - aws / s3(LoadError)
The crontab for this script looks like this:
此脚本的crontab如下所示:
0 3 * * * ~/Downloader/download.rb > ~/Downloader/output.log 2>&1
I originally thought it might be because cron is running as a different user, but when I do a 'whoami' at the start of my ruby script it tells me it's running as the same user I always use.
我原本以为这可能是因为cron作为一个不同的用户运行,但是当我在ruby脚本的开头做一个'whoami'时,它告诉我它是以我一直使用的同一个用户运行的。
I have also done a bundle init and added the gem to my gemfile, but this doesn't seem to have any affect.
我还做了一个bundle init并将gem添加到我的gemfile中,但这似乎没有任何影响。
Why does cron fail to load the gem? I am running Ubuntu.
为什么cron无法加载gem?我正在运行Ubuntu。
5 个解决方案
#1
12
If you're running it manually and it works you're probably in a different shell environment than cron is executing in. Since you mention you're on Ubuntu, the cron jobs probably execute under /bin/sh, and you're manually running them under /bin/bash if you haven't changed anything.
如果您正在手动运行它并且它可以工作,那么您可能处于与cron正在执行的不同的shell环境中。由于您提到您在Ubuntu上,因此cron作业可能在/ bin / sh下执行,而您手动执行如果你没有改变任何东西,在/ bin / bash下运行它们。
You can debug your environment problems or you can change the shell that your job runs under.
您可以调试环境问题,也可以更改作业运行的shell。
To debug, There are several ways to figure out what shell your cron jobs are using. It can be defined in
要进行调试,有几种方法可以确定您的cron作业使用的shell。它可以在中定义
/etc/crontab
or you can make a cron job to dump your shell and environment information, as has been mentioned in this SO answer: How to simulate the environment cron executes a script with?
或者你可以创建一个cron作业来转储你的shell和环境信息,正如在这个SO答案中提到的:如何模拟环境cron执行一个脚本?
To switch to that shell and see the actual errors causing your job to fail, do
要切换到该shell并查看导致作业失败的实际错误,请执行此操作
sudo su
env -i <path to shell> (e.g. /bin/sh)
Then running your script you should see what the errors are and be able to fix them (rubygems?).
然后运行你的脚本你应该看到错误是什么,并能够解决它们(rubygems?)。
Option 2 is to switch shells. You can always try something like:
选项2是切换外壳。您可以尝试以下方式:
0 3 * * * /bin/bash -c '~/Downloader/download.rb > ~/Downloader/output.log 2>&1'
To force your job into bash. That might also clear things up.
强迫你的工作进入bash。这也许可以解决问题。
#2
22
As mentioned here https://coderwall.com/p/vhv8aw you can simply try
正如这里提到的https://coderwall.com/p/vhv8aw你可以试试
rvm cron setup # let RMV do your cron settings
rvm cron setup#let RMV执行你的cron设置
Make sure that you make copy of your crontab before running this command
在运行此命令之前,请确保复制crontab
#3
5
You may also explicitly set your Gem path:
您还可以明确设置Gem路径:
GEM_HOME="/usr/local/rvm/gems/ruby-1.9.2-p290@my-special-gemset"
GEM_HOME = “/ usr/local/rvm/gems/ruby-1.9.2-p290@my-special-gemset”
#4
2
Add this at the beginning of your cron
在你的cron开头添加它
PATH="/home/user/.rvm/gems/ruby-2.1.4/bin:/home/user/.rvm/gems/ruby-2.1.4@global/bin:/home/user/.rvm/rubies/ruby-2.1.4/bin:/home/user/.rvm/gems/ruby-2.1.4/bin:/home/user/.rvm/gems/ruby-2.1.4@global/bin:/home/user/.rvm/rubies/ruby-2.1.4/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/home/user/.rvm/bin:/usr/local/sbin:/usr/sbin:/home/user/.rvm/bin:/home/user/.local/bin:/home/user/bin"
GEM_HOME='/home/user/.rvm/gems/ruby-2.1.4'
GEM_PATH='/home/user/.rvm/gems/ruby-2.1.4:/home/user/.rvm/gems/ruby-2.1.4@global'
MY_RUBY_HOME='/home/user/.rvm/rubies/ruby-2.1.4'
IRBRC='/home/user/.rvm/rubies/ruby-2.1.4/.irbrc'
RUBY_VERSION='ruby-2.1.4'
#5
0
in a non cron environment execute echo $PATH
, copy the path and paste it into your crontab, before your command:
在非cron环境中执行echo $ PATH,复制路径并将其粘贴到crontab中,然后再执行命令:
echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
and inside crontab:
在crontab里面:
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
0 3 * * * ~/Downloader/download.rb > ~/Downloader/output.log 2>&1
#1
12
If you're running it manually and it works you're probably in a different shell environment than cron is executing in. Since you mention you're on Ubuntu, the cron jobs probably execute under /bin/sh, and you're manually running them under /bin/bash if you haven't changed anything.
如果您正在手动运行它并且它可以工作,那么您可能处于与cron正在执行的不同的shell环境中。由于您提到您在Ubuntu上,因此cron作业可能在/ bin / sh下执行,而您手动执行如果你没有改变任何东西,在/ bin / bash下运行它们。
You can debug your environment problems or you can change the shell that your job runs under.
您可以调试环境问题,也可以更改作业运行的shell。
To debug, There are several ways to figure out what shell your cron jobs are using. It can be defined in
要进行调试,有几种方法可以确定您的cron作业使用的shell。它可以在中定义
/etc/crontab
or you can make a cron job to dump your shell and environment information, as has been mentioned in this SO answer: How to simulate the environment cron executes a script with?
或者你可以创建一个cron作业来转储你的shell和环境信息,正如在这个SO答案中提到的:如何模拟环境cron执行一个脚本?
To switch to that shell and see the actual errors causing your job to fail, do
要切换到该shell并查看导致作业失败的实际错误,请执行此操作
sudo su
env -i <path to shell> (e.g. /bin/sh)
Then running your script you should see what the errors are and be able to fix them (rubygems?).
然后运行你的脚本你应该看到错误是什么,并能够解决它们(rubygems?)。
Option 2 is to switch shells. You can always try something like:
选项2是切换外壳。您可以尝试以下方式:
0 3 * * * /bin/bash -c '~/Downloader/download.rb > ~/Downloader/output.log 2>&1'
To force your job into bash. That might also clear things up.
强迫你的工作进入bash。这也许可以解决问题。
#2
22
As mentioned here https://coderwall.com/p/vhv8aw you can simply try
正如这里提到的https://coderwall.com/p/vhv8aw你可以试试
rvm cron setup # let RMV do your cron settings
rvm cron setup#let RMV执行你的cron设置
Make sure that you make copy of your crontab before running this command
在运行此命令之前,请确保复制crontab
#3
5
You may also explicitly set your Gem path:
您还可以明确设置Gem路径:
GEM_HOME="/usr/local/rvm/gems/ruby-1.9.2-p290@my-special-gemset"
GEM_HOME = “/ usr/local/rvm/gems/ruby-1.9.2-p290@my-special-gemset”
#4
2
Add this at the beginning of your cron
在你的cron开头添加它
PATH="/home/user/.rvm/gems/ruby-2.1.4/bin:/home/user/.rvm/gems/ruby-2.1.4@global/bin:/home/user/.rvm/rubies/ruby-2.1.4/bin:/home/user/.rvm/gems/ruby-2.1.4/bin:/home/user/.rvm/gems/ruby-2.1.4@global/bin:/home/user/.rvm/rubies/ruby-2.1.4/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/home/user/.rvm/bin:/usr/local/sbin:/usr/sbin:/home/user/.rvm/bin:/home/user/.local/bin:/home/user/bin"
GEM_HOME='/home/user/.rvm/gems/ruby-2.1.4'
GEM_PATH='/home/user/.rvm/gems/ruby-2.1.4:/home/user/.rvm/gems/ruby-2.1.4@global'
MY_RUBY_HOME='/home/user/.rvm/rubies/ruby-2.1.4'
IRBRC='/home/user/.rvm/rubies/ruby-2.1.4/.irbrc'
RUBY_VERSION='ruby-2.1.4'
#5
0
in a non cron environment execute echo $PATH
, copy the path and paste it into your crontab, before your command:
在非cron环境中执行echo $ PATH,复制路径并将其粘贴到crontab中,然后再执行命令:
echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
and inside crontab:
在crontab里面:
PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin
0 3 * * * ~/Downloader/download.rb > ~/Downloader/output.log 2>&1