Назад | Перейти на главную страницу

Загрузить переменные среды пользователя в cronjob

Как я могу загрузить переменные среды пользователя в cronjob?


У меня есть cronjob, который должен запускать скрипт каждую минуту на моей машине Ubuntu:

* * * * * /home/user/myscript.sh;

В этом скрипте я хочу использовать переменные среды, например $JAVA_HOME и $M2_HOME для автоматического запуска процесса сборки. Проблема в том, что эти переменные установлены в .bashrc через export JAVA_HOME=/../...

Следовательно, я source эти файлы перед выполнением моего скрипта:

* * * * * source ~/.bash_profile; source ~/.bashrc; /home/user/myscript.sh;

Однако переменные не установлены! Чтобы проверить это, я echo переменные среды через env в файл журнала:

env >> ~/env.log
echo $M2_HOME >> ~/env.log

В файле журнала все еще нет переменных. К файлу добавляются только следующие элементы (нет $M2_HOME и т.д.):

LANGUAGE=en_US:en
HOME=/home/user
LOGNAME=user
PATH=/usr/bin:/bin
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/home/user

Если я запустил сценарий прямо в своей оболочке, все переменные распечатываются в env.log.

То же самое происходит, когда я ставлю source команды в файл сценария. Только если я удалю export ключевое слово перед объявлением переменной это видно по echo $var команда. Но это не решение, потому что я не управляю этими объявлениями.


Я попробовал решение @tripplee с ограниченной проблемой оболочки sh, но оно все равно не работает. Далее я сократил его до очень простого задания cron без второго скрипта, чтобы показать проблему:

* * * * * . $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log;

cat /home/user/env.log:

LANGUAGE=en_US:en
HOME=/home/user
LOGNAME=user
PATH=/usr/bin:/bin
LANG=en_US.UTF-8
SHELL=/bin/sh
PWD=/home/user

Чтобы добавить к ответу tripleee, вы можете вызвать оценку всех ваших кронов в bash (или в оболочке по вашему выбору), указав оболочку в crontab.

SHELL=/bin/bash
* * * * * . $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log;

редактировать и если вы действительно хотите увидеть, что он делает, следующая команда должна сделать его достаточно подробным:

/bin/bash -x -c '. $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log' > /tmp/cron.`date +\%s` 

set -x или флаг -x в командной строке заставит большинство оболочек печатать каждую вычисленную строку.

Для проверки в командной строке удалите \ из команды даты. Это необходимо, чтобы cron не оценивал% s как стандартный ввод.

Синтаксис задания cron ограничен sh только чтобы вы не могли использовать башизмы вроде ~. К счастью, исправить это просто - просто замените его на $HOME. Так же, source необходимо заменить на . (просто точка).

Конечно, исходные скрипты не должны использовать синтаксис Bash, если вы собираетесь использовать их из sh. Вероятно, самое простое решение - перенести эти вещи в ваш скрипт (или создать скрипт-оболочку для запуска Cron).

Потому что внутри вашего скрипта вы можете использовать bash если хотите, при условии, конечно, что линия shebang правильно #!/bin/bash (при необходимости измените путь), а не #!/bin/sh.

Если вам это по какой-то причине не нравится, вы можете встроить Bash в свой crontab файл, указав его явно:

* * * * * bash -c 'source ~/.bash_profile; source ~/.bashrc; ./myscript.sh'

Вы должны увидеть source: command not found и export: command not found в электронных письмах, отправленных cron когда дела идут плохо. Изучение вывода ошибок действительно важно для устранения неполадок.

Конечно, если у вас есть стандартный .bashrc в Ubuntu он немедленно выйдет из строя, если вы попытаетесь получить его из неинтерактивного скрипта. Может быть, лучше поместить нужные вам настройки для неинтерактивного использования в другой файл (возможно, .profile который будет читать sh по умолчанию)?

У тебя нет полный tty в cron. Но если вы запустите его через sudo -i вы получите один.

* * * * * sudo -u user -i bash -c '. $HOME/.bash_profile; . $HOME/.bashrc; env > $HOME/env.log;'

Или для запуска скрипта:

* * * * * sudo -u user -i bash -c '. $HOME/.bash_profile; . $HOME/.bashrc; /home/user/myscript.sh;'

Если поставить source команды в Баш скрипт, запускающий целевой скрипт, вы получите аккуратный:

* * * * * sudo -u user -i /home/user/mystarter.sh;