Необходимо настроить среду rvm перед каждым заданием cron

#cron #rvm #crontab

#rvm #cron

Вопрос:

Я установил и настроил RVM, примерно следуя шаблону, описанному в первой части этого набора инструкций:http://blog.ninjahideout.com/posts/a-guide-to-a-nginx-passenger-and-rvm-server

По сути, это означает, что нет предварительной сборки системы ruby (все установки ruby управляются RVM) и RVM устанавливается в масштабах всей системы, а не привязан к конкретному пользователю (файлы в /usr/local/rvm ), поэтому все пользователи в rvm группе могут получить доступ к одним и тем же rubies с одними и теми же установленными gems.

Одна из проблем с настройкой системы таким образом заключается в том, что среда rvm должна быть настроена в сеансе командной строки, прежде чем ruby можно будет использовать. Для всех пользователей rvm я помещаю это в их .bashrc: source "/usr/local/rvm/scripts/rvm" . Это отлично работает для сеансов ssh.

Проблема возникает для заданий cron, которые не выполняются .bashrc. Приведенный выше сценарий 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).

Ответ №1:

Просто сделайте rvm cron setup

Это позволяет rvm настроить параметры ruby cron. В результате crontab заполняется назначениями переменных среды.

Затем crontab -e

Добавьте свои задачи cron (под назначениями), сохраните и закройте, и все готово!!

Комментарии:

1. только это продвижение помогает мне

2. это неисправно и не было исправлено в течение длительного времени 🙁

Ответ №2:

Вам не нужно писать оболочки (следуя этой логике, вы могли бы также написать оболочку для оболочки). Пожалуйста, сохраняйте простоту. Все, что вам нужно сделать, это настроить ваше задание cron на запуск оболочки bash и заставить эту оболочку bash загружать вашу среду.

Строка shebang в вашем скрипте должна ссылаться не непосредственно на исполняемый файл ruby, а на ruby rvm:

 #!/usr/bin/env ruby
  

Это предписывает скрипту загрузить среду и запустить ruby, как мы бы делали в командной строке с загруженным rvm.

Во многих системах, производных от UNIX, crontabs может иметь раздел конфигурации перед фактическими строками, которые определяют задания, которые будут выполняться. Если это так, вам следует указать:

 SHELL=/path/to/bash  
  

Это гарантирует, что задание cron будет создано из bash. Тем не менее, ваша среда отсутствует, поэтому, чтобы дать указание bash загрузить вашу среду, вы захотите добавить в раздел конфигурации следующее:

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

HOME автоматически выводится из строки /etc /passwd владельца crontab, но вы можете переопределить ее.

 HOME=/path/to/home
  

После этого задание cron может выглядеть следующим образом:

 15 14 1 * *     $HOME/rvm_script.rb
  

Что, если ваш crontab не поддерживает раздел конфигурации? Что ж, вам придется указывать все директивы среды в одной строке вместе с самим заданием. Например,

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

Полный пост в блоге на эту тему

Комментарии:

1. Дэниел — Возможно, вы захотите изменить этот отличный ответ, чтобы сделать его более справочным, указав, куда именно вводится материал rvm с помощью параметра BASH_ENV. В моем случае это было из /etc/profile.d/rvm.sh (CentOS 5). Крис

Ответ №3:

Файлы Crontab обычно допускают только два типа действий (плюс комментарии и пустые строки, если вы хотите быть педантичным):

  1. Настройка переменной среды.
  2. Спецификации команды.

И некоторые 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
  

Шесть из одного, полдюжины из другого.

Комментарии:

1. Спасибо! я подозревал (беспокоился), что это будет ответом, но я рад получить некоторое подтверждение того, что я не просто что-то пропустил в документах.

2. Моя версия sh (bourne shell) не знает, что такое «исходный код». Мне нужно было изменить shebang на #!/bin/bash .

3. @labyrinth AFAIK . "/usr/local/rvm/scripts/rvm" должен работать в строгом /bin/sh режиме.

Ответ №4:

Если ваш cronjob представляет собой обычный файл ruby, в документах говорится, что вы можете просто использовать встроенную оболочку, которая загрузит правильную версию ruby и gemset:

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

Однако вам все равно нужно будет добавить этот вызов в каждую строку.