Где я могу установить переменные среды, которые будут использовать crontab?


у меня есть файл crontab каждый час. Пользователь, запускающий его, имеет среду без переменных в .bash_profile это работает, когда пользователь запускает задание с терминала, однако, очевидно, что они не получают подобран crontab, когда он работает.

Я пытался установить их в .profile и .bashrc но они все равно не забирают. Кто-нибудь знает, где я могу поместить среду vars, которую может забрать crontab?

12 201

12 ответов:

есть '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 `
cmd=${REAL_HOME:-/real/home}/bin/$base

if [ ! -x $cmd ]
then cmd=${HOME}/bin/$base
fi

exec $cmd ${@:+"$@"}

(написано с использованием старого стандарта кодирования-в настоящее время я бы использовал shebang '#!- с самого начала.)

The'~/.cronfile ' - это вариант моего профиля для использования cron-строго неинтерактивный и без эха ради того, чтобы быть шумный. Вы могли бы организовать, чтобы выполнить .профиль и так далее вместо. (Материал 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 в настоящее время используют vixie-cron что позволяет объявлять их в файле crontab (также GNU mcron).

Archlinux и RedHat использовать cronie, который не разрешить переменные среды должны быть объявлены и будут вызывать синтаксические ошибки в cron.бревно. Обходной путь может быть сделан для каждой записи:

# 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/.файл профиля.

конечно $HOME также не установлен, вы должны заменить его на полный путь вашего $HOME.

установка vars в /etc/environment также работал для меня в Ubuntu. Начиная с 12.04, переменные в/etc / environment загружаются для cron.

расширение на примере @carestad, который я нахожу проще, заключается в том, чтобы запустить скрипт с cron и иметь среду в скрипте.

в файле crontab-e:

SHELL=/bin/bash

*/1 * * * * $HOME/cron_job.sh

In cron_job.sh файл:

#!/bin/bash
source $HOME/.bash_profile
some_other_cmd

любая команда после источник .файл будет иметь свою среду, как будто вы вошли в систему.

для меня я должен был установить переменную окружения для php-приложения. Я перестроил его, добавив следующий код в мой crontab.

$ sudo  crontab -e

crontab:

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
...

расширение на @Robert Brisita просто расширяется, также если вы не хотите настраивать все переменные профиля в скрипте, вы можете выбрать переменные для экспорта в верхней части скрипта

в файле crontab-e:

SHELL=/bin/bash

*/1 * * * * /Path/to/script/script.sh

In script.sh

#!/bin/bash
export JAVA_HOME=/path/to/jdk

some-other-command

вместо

0  *  *  *  *  sh /my/script.sh

используйте bash-l-c

0  *  *  *  *  bash -l -c 'sh /my/script.sh'

другой способ - вдохновленный этой ответ - для" введения " переменных используется следующее (пример fcron):

%daily 00 12 \
    set -a; \
    . /path/to/file/containing/vars; \
    set +a; \
    /path/to/script/using/vars

С help set:

-метка переменных, которые изменяются или создаются для экспорта.

использование + вместо - приводит к отключению этих флагов.

так что все что между set - и set + экспортируется в env и затем доступен для других сценариев и т. д. Без используя set переменные получают источник, но живут в set только.

кроме того, также полезно передавать переменные, когда программа требует запуска учетной записи без root, но вам понадобятся некоторые переменные внутри среды этого другого пользователя. Ниже приведен пример передачи в nullmailer vars для форматирования заголовка электронной почты:

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 это проверяет текущий набор параметров в текущей оболочке, чтобы определить, что оболочка работает в интерактивном режиме. Если оболочка работает в интерактивном режиме, то она переходит к поиску . Однако, в оболочке, вызываемой cron на $- переменная не содержит i значение, которое указывает на интерактивность. Таким образом,~/.bashrc файл никогда не получает источник полностью. В результате переменные среды так и не были установлены. Если это ваша проблема, не стесняйтесь комментировать блок кода следующим образом и повторите попытку:

# case $- in
#     *i*) ;;
#     *) return;;
# esac

надеюсь, это окажется полезным

Если вы запускаете скрипты, которые вы выполняете через cron с:

#!/bin/bash -l

они должны забрать свой ~/.файл переменные среды