在 cron 中设置路径,以便它可以找到 ruby

Posted

技术标签:

【中文标题】在 cron 中设置路径,以便它可以找到 ruby【英文标题】:Setting path for whenever in cron so it can find ruby 【发布时间】:2011-08-15 16:39:10 【问题描述】:

我的 ruby​​ 在 /usr/local/bin 中。 whenever 找不到它,并且在我的 cron 文件顶部设置 PATH 也不起作用,我认为是因为无论何时在新的 bash 实例中运行命令。

# 这不起作用 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin # 每当生成任务时开始: foo 0 * * * * /bin/bash -l -c 'cd /srv/foo/releases/20110429110637 && script/rails runner -e production '\''ActiveRecord::SessionStore::Session.destroy_recent(15)'\' '' # 每当生成任务时结束: foo

我如何知道我的 ruby​​ 二进制文件在哪里?从 /usr/bin 建立符号链接对我来说似乎很麻烦,但我想这可能是唯一的选择。

This question 在 schedule.rb 中提供env :PATH, "..." 作为解决方案,但是(a)我在文档中的任何地方都找不到该功能的任何文档(b)它似乎没有解决提问者的问题(不幸的是,我只是尝试它需要不平凡的周转时间)。 更新其实it is in the bottom of this page,我现在就试试。

更多信息

    我无法修改 cron 命令,因为它是由无论何时生成的 我验证了如果我使用bash -l 创建一个新的 bash shell,/usr/bin/env 会发现 ruby​​ 就可以了 我刚刚在该用户的命令行中尝试了 cron 中的确切命令(从 /bin/bash 开始),它成功了。

所以,这很神秘……

【问题讨论】:

你说你在 /usr/local/bin 中有 ruby​​,但你没有将它包含在你的 PATH 中?添加 :/usr/local/bin 应该可以工作(我检查了我的一个 cron 文件,它完全一样) 【参考方案1】:

解决办法是把这个放到schedule.rb:

env :PATH, ENV['PATH']

Here's a little guide I put together on the topic.

【讨论】:

您还有其他意见吗?我添加了这个,我在 cron.log 中得到了同样的错误,我确定我的路径是正确的。我什至可以运行 /usr/local/bin/ruby -v 并得到正确的响应 好吧,这似乎不再适用于我拥有的最新版本?? 如果您愿意,您可以将其缩减为 "env :PATH, ENV['PATH']" 以自动设置而不是硬编码。 由于某种原因,这种方法对我不起作用,所以我最终添加了所有环境,而不仅仅是路径 ENV.each |k, v| env(k, v) 【参考方案2】:

将你的 crontab 重写为

0 * * * *  PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/sbin ; export PATH ;/bin/bash -l -c 'cd /srv/foo/releases/20110429110637 && script/rails runner -e production '\''ActiveRecord::SessionStore::Session.destroy_recent(15)'\''' ; 

或者您应该尝试弄清楚为什么您的 BASH shell 没有选择 PATH=...,这几乎可以肯定是在您的 .profile 或 .bash_profile 中。

我希望这会有所帮助。

【讨论】:

谢谢,根据您的回复为我的问题添加了更多信息【参考方案3】:

正如 John Bachir 指出的,您可以通过 env 进行操作。但让我添加更多输入。我正在 AWS Opsworks 上进行部署。不幸的是,他们没有默认安装 ruby​​ 管理器(RVM、Rbenv 等)。

我需要做的第一件事是通过 SSH 连接到实例并找出我正在使用的 ruby​​。这很容易通过在终端中执行which ruby 命令。

$ which ruby
/usr/local/bin/ruby

Cron 使用位于 /usr/bin/ruby 的 ruby​​。这需要改变。

在 schedule.rb 中,我有:

set :env_path, ''
env :PATH, @env_path if @env_path.present?

在本地,env_path 不需要设置。对于大多数用户来说,唯一要做的就是随时执行:

bundle exec whenever --set 'environment=development' --update-crontab

在暂存/生产环境中,ruby 可能安装在其他地方。所以运行这个可能更合适:

bundle exec whenever --set 'environment=staging&env_path=/usr/bin/local' --update-crontab

您需要将/usr/bin/local 替换为echo $PATH 的输出。

然而,在 Opsworks 中,我需要创建一个自定义 Chef 食谱,如下所示:

node[:deploy].each do |application, deploy|
  execute 'whenever' do
    user 'deploy'
    group 'nginx'
    cwd "#deploy[:deploy_to]/current"
    command "bundle exec whenever --set 'environment=#deploy[:environment_variables][:RAILS_ENV]&env_path=#ENV['PATH']' --update-crontab"
  end
end

我希望这里的信息足够清楚。

【讨论】:

以上是关于在 cron 中设置路径,以便它可以找到 ruby的主要内容,如果未能解决你的问题,请参考以下文章

在 windows 的 django 中设置一个 cron 作业

如何让 CRON 调用正确的路径

在 Gemfile 中设置 ruby​​ 版本

在 Windows 中设置 cron 作业

如何在symfony 2.x中设置控制台命令的定时器?

如何在 Tomcat 中设置上下文路径,以便在不附加部署文件夹名称的情况下进入站点?