【问题标题】:Need to set up rvm environment prior to every cron job需要在每个 cron 作业之前设置 rvm 环境
【发布时间】:2011-04-15 17:55:57
【问题描述】:

我大致按照这组说明第一部分中概述的模式安装和配置了 RVM:http://blog.ninjahideout.com/posts/a-guide-to-a-nginx-passenger-and-rvm-server

基本上,这意味着没有预构建系统 ruby​​(所有 ruby​​ 安装都由 RVM 管理)并且 RVM 是在系统范围内安装的,而不是附加到特定用户(/usr/local/rvm 处的文件),因此所有用户在rvm 组可以使用相同的已安装 gem 访问相同的红宝石。

以这种方式设置系统的一个问题是必须在 shell 会话中设置 rvm 环境,然后才能使用 ruby​​。对于所有 rvm 用户,我将其放在他们的 .bashrc 中:source "/usr/local/rvm/scripts/rvm"。这适用于 ssh 会话。

问题在于不执行 .bashrc 的 cron 作业。上面的 rvm 脚本 (/usr/local/rvm/scripts/rvm) 比设置一些环境变量要复杂得多,所以我实际上想在文件中的每个作业之前运行这个命令。

当然,我可以手动完成,就像这样:

1 2 * * * source "/usr/local/rvm/scripts/rvm"; /do/some/cron/job/1
3 4 * * * source "/usr/local/rvm/scripts/rvm"; /do/some/cron/job/2
5 6 * * * source "/usr/local/rvm/scripts/rvm"; /do/some/cron/job/3
7 8 * * * source "/usr/local/rvm/scripts/rvm"; /do/some/cron/job/4

但我更喜欢这样做:

[execute] source "/usr/local/rvm/scripts/rvm"

1 2 * * * /do/some/cron/job/1
3 4 * * * /do/some/cron/job/2
5 6 * * * /do/some/cron/job/3
7 8 * * * /do/some/cron/job/4

显然,上述语法不起作用。但是,有什么方法可以让它工作吗? cron 手册页和文档在这里没有太大帮助。但是有一些技巧或标准方法可以实现这一点吗?

如果重要的话,我正在运行 Ubuntu 10.10 (Maverick Meerkat)。

【问题讨论】:

    标签: cron rvm crontab


    【解决方案1】:

    只要rvm cron setup

    这让我们 rvm 设置 ruby​​ cron 设置

    然后crontab -e

    添加您的 cron 任务,保存并关闭,一切顺利!

    【讨论】:

    • 只有这个进步对我有帮助
    【解决方案2】:

    您不需要编写包装器(按照该逻辑,您不妨为包装器编写一个包装器)。请保持简单。您需要做的就是配置您的 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

    【讨论】:

    • Daniel - 您可能想要修改这个出色的答案,通过注意通过 BASH_ENV 设置引入 rvm 内容的确切位置,使其更具参考性。就我而言,它来自 /etc/profile.d/rvm.sh (CentOS 5)。克里斯
    【解决方案3】:

    Crontab files 一般只允许两种类型的东西(如果你想学究,加上 cmets 和空行):

    1. 环境变量设置。
    2. 命令规范。

    some crontabs 甚至不支持设置环境变量(虽然我怀疑你会遇到这样的做法)。

    如果您需要做的不仅仅是设置一些环境变量,那么您需要将您的 source "/usr/local/rvm/scripts/rvm" 放入您的问题中的 cron 规范中,或者您需要将您的 cron 作业包装在cron runner 是这样的:

    #!/bin/sh
    source "/usr/local/rvm/scripts/rvm"
    exec $1
    

    然后在 crontab 中:

    1 2 * * * /path/rvm_cron_runner /do/some/cron/job/1
    

    六个一个,六个另一个。

    【讨论】:

    • 谢谢!我怀疑(担心)这将是答案,但我很高兴得到一些确认,我不只是遗漏了文档中的某些内容。
    • 我的 sh (bourne shell) 版本不知道“源”是什么。我需要将 shebang 更改为 #!/bin/bash
    • @labyrinth AFAIK . "/usr/local/rvm/scripts/rvm" 应该在严格的/bin/sh 中工作。
    【解决方案4】:

    如果你的 cronjob 是一个直接的 ruby​​ 文件,docs 说你可以使用内置的包装器来加载正确的 ruby​​ 版本和 gemset:

    1 0  * * * /usr/local/rvm/bin/ruby-1.9.2-p290@projectX /path/to/script.rb
    

    但是,您仍然需要将此调用添加到每一行。

    【讨论】:

      猜你喜欢
      • 2018-04-09
      • 1970-01-01
      • 2011-11-05
      • 2014-06-23
      • 2014-10-07
      • 1970-01-01
      • 2020-02-05
      • 2015-01-09
      • 2013-03-11
      相关资源
      最近更新 更多