如何使用 rbenv 和 cron 运行 Ruby 脚本
Posted
技术标签:
【中文标题】如何使用 rbenv 和 cron 运行 Ruby 脚本【英文标题】:How to run a Ruby script using rbenv with cron 【发布时间】:2012-01-16 02:55:10 【问题描述】:我正在尝试使用带有 cron 的 rbenv 运行 Ruby 脚本。 我知道我需要加载 rbenv 才能加载正确的 Ruby 版本。
我尝试过这样的选项:
*/10 * * * * /bin/bash -c 'source $HOME/.bashrc; cd /数据/应用程序; ruby -v' >> /tmp/logfile.txt 2>&1
但由于会话不是交互式的,我没有正确的 Ruby 版本。 我找到了这样的例子:
15 14 1 * * export BASH_ENV=/path/to/environment && /full/path/to/bash -c '/full/path/to/rvm_script.rb'
它也没有工作。然后我写了一个加载器,它只加载当前shell中的rbenv但它不起作用。
*/1 * * * * /bin/bash -c '$HOME/.rbenv/loader.sh ; cd /数据/应用程序/; ruby -v ' >> /tmp/logfile.txt 2>&1
现在我正在寻找另一种加载方式……有什么想法吗?
【问题讨论】:
【参考方案1】:我找到了加载 rbenv 的解决方案。使用加载器将 rbenv 导入到 PATH :
*/1 * * * * /bin/bash -c '. $HOME/.rbenv/loader.sh ; cd /数据/应用程序/;红宝石-v'
'.'在 '$HOME/.rbenv/loader.sh' 重要之前,它会在当前 shell 中运行脚本
或者没有加载器,哪个更好:
*/1 * * * * /bin/bash -c 'export PATH="$HOME/.rbenv/bin:$PATH" ; eval "$(rbenv init -)"; cd /数据/应用程序/;红宝石-v'
【讨论】:
请注意,您的加载程序只需要包含$PATH
更改:export PATH=$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH
。而且您甚至不必 cd,只需运行ruby /data/app/script_name.rb
,rbenv 就会找到正确的版本。如您所知,如果不需要 shims 路径,可以省略它。
* * * * * * /bin/bash -c '. /etc/profile.d/rbenv.sh; ruby -v'
用于系统范围的 rbenv 安装和没有外壳/主目录的用户
您可以在整个 crontab 中设置 PATH ,而不仅仅是针对特定条目。 ***.com/a/2409369/629057【参考方案2】:
更好的解决方案是简单地使用命令bash -lc
命令。这将读取您的 bash 配置文件,该文件将设置 rbenv。来自bash
手册页:
-l 使 bash 像作为登录 shell 调用一样工作
当 bash 作为交互式登录 shell 或作为带有 --login 选项的非交互式 shell 调用时,它 如果该文件存在,首先从文件 /etc/profile 读取并执行命令。读取该文件后,它 按顺序查找 ~/.bash_profile、~/.bash_login 和 ~/.profile,并从 第一个存在且可读的。启动 shell 时可以使用 --noprofile 选项来禁止 这种行为。
【讨论】:
我不推荐这样做,因为如果.bash_profile
等执行只有交互式 shell 需要的东西,它可能会增加很多开销。如果你给某些 bash 命令起别名,你甚至可能会造成麻烦。
也许这会有所帮助 eq8.eu/blogs/15-cron-rbenv-bundle-exec-rake-task * * * * * PATH=$PATH:/usr/local/bin && bash -lc "cd /home/deploy/apps/myapp && RACK_ENV=production bundle exec rake event:process
@EstebanFeldman 确保 'eval "$(rbenv init -)"' 在您的 .bashrc 中,并且 .bashrc 是从 .bash_profile 加载的。
这是一个无声的假设,即 cron 作业用户实际上有一个主目录。【参考方案3】:
虽然 kmmndr 的回答是正确的,但我也喜欢bash -l
-方法。
打开非交互式登录 shell 让事情变得更简单,因为我的 Rails 应用程序和 Ruby 脚本都在同一个用户下运行,所以开销不是问题。
所以不是
*/1 * * * * /bin/bash -c 'export PATH="$HOME/.rbenv/bin:$PATH" ; eval "$(rbenv init -)"; cd /data/app/; ruby -v'
我愿意
*/1 * * * * /bin/bash -lc 'cd /data/app/; ruby -v'
正如上面的回答中提到的,bash -l
的行为就像你正常登录一样,这意味着你的 rbenv 环境已经设置好了(只要你的.bashrc
、.bash_profile
中有适当的行/etc/profile.d/*
)。
如果你需要更多细节,我写了a blog post关于这个话题。
【讨论】:
【参考方案4】:对于我在 Ruby 中的备份脚本,我只需使用 ~/.rbenv/bin/rbenv exec ruby [options] /path/to/ruby/script.rb
。试试这个:
* * * * * ~/.rbenv/bin/rbenv exec ruby -v > ~/rbenv-ruby-version.txt
【讨论】:
你每分钟运行一次,每一天的每一分钟。你可能想要0 * * * *
,让它每小时运行一次。
这是为了让我可以尽快测试正确的 Ruby 是否正在运行。确认后,我删除了该行。这不是我想继续在服务器上运行的工作。实际的备份命令是另一个命令。【参考方案5】:
@Kelvin 的这个回答对我有用:
*/1 * * * * PATH=$HOME/.rbenv/bin:$HOME/.rbenv/shims:$PATH ruby -v >> ~/test.out
【讨论】:
对我来说似乎是最干净的。以上是关于如何使用 rbenv 和 cron 运行 Ruby 脚本的主要内容,如果未能解决你的问题,请参考以下文章
如何为项目设置特定的 Ruby 版本(无 rvm 和 rbenv)