Где я могу установить переменные среды, которые будет использовать crontab?
-
19-09-2019 - |
Вопрос
У меня crontab запускается каждый час.Пользователь, запускающий его, имеет переменные среды в .bash_profile
это работает, когда пользователь запускает задание с терминала, однако, очевидно, они не подхватываются crontab при его запуске.
Я попробовал их установить .profile
и .bashrc
но их, похоже, до сих пор не забрали.Кто-нибудь знает, где я могу поместить переменные среды, которые может подобрать crontab?
Решение
Попросите «cron» запустить сценарий оболочки, который устанавливает среду перед запуском команды.
Всегда.
# @(#)$Id: crontab,v 4.2 2007/09/17 02:41:00 jleffler Exp $
# Crontab file for Home Directory for Jonathan Leffler (JL)
#-----------------------------------------------------------------------------
#Min Hour Day Month Weekday Command
#-----------------------------------------------------------------------------
0 * * * * /usr/bin/ksh /work1/jleffler/bin/Cron/hourly
1 1 * * * /usr/bin/ksh /work1/jleffler/bin/Cron/daily
23 1 * * 1-5 /usr/bin/ksh /work1/jleffler/bin/Cron/weekday
2 3 * * 0 /usr/bin/ksh /work1/jleffler/bin/Cron/weekly
21 3 1 * * /usr/bin/ksh /work1/jleffler/bin/Cron/monthly
Все скрипты в ~/bin/Cron являются ссылками на один скрипт runcron, который выглядит следующим образом:
: "$Id: runcron.sh,v 2.1 2001/02/27 00:53:22 jleffler Exp $"
#
# Commands to be performed by Cron (no debugging options)
# Set environment -- not done by cron (usually switches HOME)
. $HOME/.cronfile
base=`basename $0`
cmd=${REAL_HOME:-/real/home}/bin/$base
if [ ! -x $cmd ]
then cmd=${HOME}/bin/$base
fi
exec $cmd ${@:+"$@"}
(Написано с использованием более старого стандарта кодирования - в настоящее время я бы использовал в начале символ «#!».)
«~/.cronfile» — это вариант моего профиля для использования cron — строго неинтерактивный и без эха ради шума.Вместо этого вы можете организовать выполнение .profile и т. д.(Материал REAL_HOME является артефактом моей среды — вы можете притвориться, что это то же самое, что и $HOME.)
Итак, этот код считывает соответствующую среду, а затем выполняет версию команды, отличную от Cron, из моего домашнего каталога.Так, например, моя команда «день недели» выглядит так:
: "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
# Commands to be done each weekday
# Update ICSCOPE
n.updics
Команда «ежедневно» проще:
: "@(#)$Id: daily.sh,v 1.5 1997/06/02 22:04:21 johnl Exp $"
#
# Commands to be done daily
# Nothing -- most things are done on weekdays only
exit 0
Другие советы
Вы можете определить переменные среды в самом crontab при запуске. crontab -e
из командной строки.
LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h dom mon dow command
* * * * * sleep 5s && echo "yo"
Эта функция доступна только для определенных реализаций cron.Ubuntu и Debian в настоящее время используют Викси-Крон что позволяет объявлять их в файле crontab (также GNU Макрон).
Архлинукс и Красная Шапка использовать дружок который не разрешить объявление переменных среды и выдать синтаксические ошибки в cron.log.Обходной путь можно выполнить для каждой записи:
# m h dom mon dow command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"
У меня есть еще одно решение этой проблемы:
0 5 * * * . $HOME/.profile; /path/to/command/to/run
В этом случае он выберет все переменные среды, определенные в вашем файле. $HOME/.profile
файл.
Конечно $HOME
также не установлен, вам придется заменить его полным путем к вашему $HOME
.
Установка переменных в /etc/environment
у меня также работал в Ubuntu.По состоянию на 12.04 переменные в /etc/environment
загружаются для cron.
Расширение примера @carestad, который мне кажется проще, заключается в запуске сценария с помощью cron и включении в него среды.
В файле crontab -e:
SHELL=/bin/bash
*/1 * * * * $HOME/cron_job.sh
В файле cron_job.sh:
#!/bin/bash
source $HOME/.bash_profile
some_other_cmd
Любая команда после источника .bash_profile будет иметь вашу среду, как если бы вы вошли в систему.
Если вы запустите сценарии, которые выполняете через cron, с помощью:
#!/bin/bash -l
Они должны забрать ваш ~/.bash_profile
переменные среды
Мне пришлось установить переменную среды для приложения php.Я поменял его, добавив следующий код в свой crontab.
$ sudo crontab -e
кронтаб:
ENVIRONMENT_VAR=production
* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php
и внутри doSomethingWonderful.php я мог бы получить значение среды с помощью:
<?php
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"
Надеюсь, это поможет!
Что бы вы ни установили crontab
будет доступен в cronjobs как напрямую, так и с использованием переменных в скриптах.
Используйте их в определении cronjob.
Вы можете настроить crontab
так что он устанавливает переменные, которые затем может использовать cronjob:
$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello
Теперь файл /tmp/hello
показывает такие вещи, как:
$ cat /tmp/hello
hi man. date is Thu May 12 12:10:01 CEST 2016
hi man. date is Thu May 12 12:11:01 CEST 2016
Используйте их в скрипте, запускаемом cronjob.
Вы можете настроить crontab
так что он устанавливает переменные, которые затем могут использовать сценарии:
$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh
И скажи сценарий /tmp/myscript.sh
это так:
echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res
Он генерирует файл /tmp/myoutput.res
показывающий:
$ cat /tmp/myoutput.res
Now is Thu May 12 12:07:01 CEST 2016. myvar=hi man
Now is Thu May 12 12:08:01 CEST 2016. myvar=hi man
...
Вместо
0 * * * * sh /my/script.sh
Используйте bash -l -c
0 * * * * bash -l -c 'sh /my/script.sh'
Расширение @Robert Brisita только что расширилось, также, если вы не хотите настраивать все переменные профиля в скрипте, вы можете выбрать переменные для экспорта в верхней части скрипта.
В файле crontab -e:
SHELL=/bin/bash
*/1 * * * * /Path/to/script/script.sh
В скрипте.sh
#!/bin/bash
export JAVA_HOME=/path/to/jdk
some-other-command
Другой способ - вдохновленный этим этот ответ - для «внедрения» переменных используется следующее (пример fcron):
%daily 00 12 \
set -a; \
. /path/to/file/containing/vars; \
set +a; \
/path/to/script/using/vars
От help set
:
-a Отметить переменные, которые были изменены или созданы для экспорта.
Использование + вместо - приводит к отключению этих флагов.
Итак, все между set -
и set +
экспортируется в env
и затем доступен для других сценариев и т. д.Без использования set
переменные получают источник, но живут в set
только.
Кроме того, передавать переменные также полезно, когда для запуска программы требуется учетная запись без полномочий root, но вам потребуются некоторые переменные внутри среды другого пользователя.Ниже приведен пример передачи переменных nullmailer для форматирования заголовка электронного письма:
su -s /bin/bash -c "set -a; \
. /path/to/nullmailer-vars; \
set +a; \
/usr/sbin/logcheck" logcheck
Я попробовал большинство предложенных решений, но поначалу ничего не получалось.Однако оказывается, что не решения не сработали.Судя по всему, мой ~/.bashrc
файл начинается со следующего блока кода:
case $- in
*i*) ;;
*) return;;
esac
По сути это case statement
который проверяет текущий набор параметров в текущей оболочке, чтобы определить, что оболочка работает в интерактивном режиме.Если оболочка работает в интерактивном режиме, она переходит к поиску ~/.bashrc
файл.Однако в оболочке, вызываемой cron
, $-
переменная не содержит i
значение, которое указывает на интерактивность.Следовательно ~/.bashrc
файл никогда не получает исходный код полностью.В результате переменные среды так и не были установлены.Если это ваша проблема, не стесняйтесь закомментировать блок кода следующим образом и повторите попытку:
# case $- in
# *i*) ;;
# *) return;;
# esac
Я надеюсь, что это окажется полезным
я использую Oh-my-zsh
в моем MacBook, поэтому я пробовал много вещей, чтобы запустить задачу crontab, но, наконец, моим решением было добавление .zshrc
перед командой запуска.
*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js
Эта задача запускается каждые 30 минут и использует .zshrc
профиль для выполнения моей команды узла.
Не забудьте поставить точку перед $HOME
вар.