【问题标题】:Cron Job Rails 3 - Loading system ruby not RVM rubyCron Job Rails 3 - 加载系统红宝石而不是 RVM 红宝石
【发布时间】:2011-05-23 02:28:43
【问题描述】:

我正在尝试使用以下命令设置 cron 作业:

crontab -l


Begin Whenever generated tasks for: myapp
* * * * * /bin/bash -l -c 'cd /Users/boris/projects/myapp && script/rails runner "Resque.enqueue(MyModel)"'

我收到以下错误;我在其中看到它正在加载 Ruby 1.8。问题是我将 RVM 与 ruby​​ 1.9.2 一起使用。如何在 CRON 中指定正确的 RVM 路径?

Subject: Cron <boris@jz> /bin/bash -l -c cd /Users/boris/projects/myapp && script/rails runner "Resque.enqueue(Place)"
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=boris>
X-Cron-Env: <USER=boris>
X-Cron-Env: <HOME=/Users/boris>
Message-Id: <20110523022400.A5B242C608D@jz.local>
Date: Sun, 22 May 2011 19:24:00 -0700 (PDT)

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- bundler/setup (LoadError)
from /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
from /Users/boris/projects/myapp/config/boot.rb:6
from script/rails:5:in `require'
from script/rails:5

如何在 CRON 中指定正确的 RVM 路径?

提前致谢

ruby 路径:

/Users/boris/.rvm/rubies/ruby-1.9.2-p180/bin/ruby

【问题讨论】:

标签: ruby-on-rails-3 unix path cron rvm


【解决方案1】:

请不要在 cron 作业中使用 -l 开关。 --login 开关指示 bash 作为登录 shell 运行。因此,它将加载您的环境,并且事情可能会正常工作。但是,cron 作业本质上是非交互式、非登录 shell。像调用它们一样调用它们只是不好的做法。此外,当 bash 启动登录 shell 时,它首先加载系统环境(/etc/profile),如果该文件中的某些内容需要打印到屏幕上(如 motd),您的 cron 作业将报告如下令人讨厌的错误:

stty: TIOCGETD: 设备的 ioctl 不合适

您也不需要编写 cron 运行程序(按照这个逻辑,您不妨编写一个 cron 运行程序运行程序)。请保持简单。您需要做的就是配置您的 cron 作业以启动 bash shell,并使该 bash shell 加载您的环境。

脚本中的 shebang 行不应直接引用 ruby​​ 可执行文件,而应引用 rvm 的 ruby​​:

#!/usr/bin/env ruby

这指示脚本加载环境并运行 ruby​​,就像我们在加载了 rvm 的命令行上一样。

在许多 UNIX 派生系统上,crontab 可以在定义要运行的作业的实际行之前有一个配置部分。如果是这种情况,您将指定:

SHELL=/path/to/bash  

这将确保 cron 作业将从 bash 生成。尽管如此,您的环境仍然丢失,因此要指示 bash 加载您的环境,您需要在配置部分添加以下内容:

BASH_ENV=/path/to/environment (typically .bash_profile or .bashrc) 

HOME 自动派生自 crontab 所有者的 /etc/passwd 行,但您可以覆盖它。

HOME=/path/to/home

在此之后,cron 作业可能如下所示:

15 14 1 * *     $HOME/rvm_script.rb

如果您的 crontab 不支持配置部分怎么办。好吧,您必须将所有环境指令与作业本身放在一行中。例如,

15 14 1 * * export BASH_ENV=/path/to/environment && /full/path/to/bash -c '/full/path/to/rvm_script.rb'

Full blog post on the subject

【讨论】:

    【解决方案2】:

    您的问题是您正在执行两个命令,但不是您所期望的。这两个命令是:

    1. /bin/bash -l -c cd /Users/boris/projects/myapp
    2. script/rails runner "Resque.enqueue(MyModel)"

    只有第一个成功时才会执行第二个。我想你只需要一些引号:

    * * * * * /bin/bash -l -c 'cd /Users/boris/projects/myapp && script/rails runner "Resque.enqueue(MyModel)"'
    

    这些单引号会将您的 cd ... &amp;&amp; script/rails ... 对作为单个命令提供给 /bin/bash,并且在执行 script/rails 时应该将当前工作目录更改为您想要的。

    【讨论】:

    • @JZ:当您从正常工作的 shell 中运行它时,它可以工作吗?
    • @quest:是的,可能就是这样。对我来说闻起来像是环境变量问题,所以也许他弄错了ruby。更新后的错误消息中的路径表明他使用的是 OSX 系统 ruby​​,而不是他自己的 rvm 版本(如果他使用的是 rvm)。
    • 完全正确。这正是问题所在。如何指定 RVM 路径?
    • @JZ:尝试在您的crontab 中设置一个显式的PATH 环境变量,您应该可以说PATH=/where/ever:/some/other,就像在shell 脚本中设置它一样。
    【解决方案3】:

    最简单的解决方案是改用这个命令:

    Begin Whenever generated tasks for: myapp
    * * * * * /bin/bash -l -c 'cd /Users/boris/projects/myapp && ./script/rails runner "Resque.enqueue(MyModel)"'
    

    【讨论】:

    • 谢谢,乍一看没注意到。
    • 是的,当它在子文件夹中时,它不是必需的,只是习惯,因为 cd'd 文件夹中的脚本/二进制文件需要它 =-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 1970-01-01
    相关资源
    最近更新 更多