Як я можу запустити команду cron із наявними змінними середовища?


114

Як я можу запустити команду cron із наявними змінними середовища?

Якщо я знаходжуся в оболонці, я можу набрати echo $ORACLE_HOMEта отримати шлях. Це одна з моїх змінних довкілля, яка встановлюється в моєму ~/.profile. Однак здається, що ~/.profileне завантажуються сценарії fron cron, і тому мої сценарії виходять з ладу, оскільки $ORACLE_HOMEзмінна не встановлена.

У цьому питанні автор згадує про створення ~/.cronfileпрофілю, який встановлює змінні для cron, а потім робить вирішення для завантаження всіх своїх команд cron у сценарії, які він зберігає у своєму ~/Cronкаталозі. Файл схожий ~/.cronfileна гарну ідею, але решта відповіді здається трохи громіздкою, і я сподівався, що хтось може сказати мені простіший спосіб отримати той же результат.

Я думаю, що на початку своїх сценаріїв я міг би додати щось на кшталт, source ~/.profileале це здається, що це може бути зайвим.

Тож як я можу змусити мої сценарії cron завантажувати змінні з мого профілю інтерактивної оболонки?


Як додавання source ~/.profileдо програми надлишковим? Програми успадковують своє середовище від викликає програми. Якщо ця програма для виклику не є вашою оболонкою, то як програма, яка займається програмою, отримає необхідне оточення?
Арседж

Я вже написав свою відповідь на подібне запитання тут. Він просто використовується su -lдля налаштування нормального середовища входу, включаючи $ PATH або для root, або для іншого конкретного користувача.
таскет

Відповіді:


141

У кронтабі, перед тим, як командувати, додайте . $HOME/.profile. Наприклад:

0 5 * * * . $HOME/.profile; /path/to/command/to/run

Cronнічого не знає про вашу оболонку; він запускається системою, тому він має мінімальне середовище. Якщо ви хочете чогось, вам потрібно мати те, що принесло в собі.


14
Що робить .сценарій раніше? (не впевнений, як би я це зробив man). Чому це відрізняється від source?
cwd

25
.Команда вихідна команда для source. Вони еквівалентні в оболонці і трохи легше набирати, особливо в межах кронтабу. Щоб отримати більше інформації, типу help .або виконати пошук ^SHELL BUILTIN COMMANDSв довідковій сторінці для bashабо у верхній частині man zshbuiltins . Running типу .` скаже вам , що команда є вбудованої.
Арседж

9
В залежності від розподілу Linux, вам , можливо , буде потрібно змінити з .profileдопомогою .bash_profile. Перевірте, який .profileфайл існує в домашній директорії користувача.
Морозний Z

@Arcege Це не працює для мене (Fedora Core 21), і я вважаю, що рівень оболонки знижується назад. Натомість, що НЕ працює, якщо ви його джерелом.
Річард Т

3
Цілком імовірно, що якщо він не працює, це тому, що сценарій SHELL для cron не налаштований на башти, тому він не буде виконаний так, як ви могли очікувати.
Деніел Фаррелл

40

Інший варіант, який мені здається легшим, - це запустити скрипт із 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 матиме ваше оточення, як ніби ви ввійшли в систему.


5
Під час роботи на AWS Linux AMI мені навіть не спало на думку, що cron не буде використовувати /bin/bashяк оболонку. Мені було цікаво, чому подібні речі cd /path/to/project; source .varsбудуть працювати, коли я їх вводив вручну, але File not foundвийшов би з ладу ( ) під час включення в cronjob. Ключовим рядком для мене було встановлення, SHELL=/bin/bashщоб я міг реально використовувати знайомі команди bash у кожному cronjob. /bin/sh/(мабуть, оболонка cron за замовчуванням) дуже обмежує.
Хартлі Броди

Це дуже погано, що ви не можете вказати файли оточення у верхній частині cron, як ви можете вказати окремі змінні середовища. У Systemd є EnvironmentFileблок обслуговування. Занадто поганий крон не має нічого подібного.
radtek

ВИ СИЛУЙТЕ всі сценарії використовувати / bin / bash у всіх crontab, що не є хорошою ідеєю, а також, що стосується вашої лінії cron: * / 1 * * * * $ HOME / cron_job.sh ... * / 1 добре для ЧОГО ?!? одна зірка означає, що вона буде виконуватися щохвилини / 1 засіб буде виконуватися щохвилини, як відповідь у розумній спільноті це жахливий гріх, тепер я вважаю, що ви дуже заплутані, щоб сказати найкраще ... вибачте
THESorcerer

1
Це те, що називається прикладом. Не соромтеся підлаштовуватися під свої потреби або взагалі не використовуйте їх. Різні штрихи для різних людей.
Роберт Брізіта

4
Якщо $SHELLє /bin/sh, то sourceкоманда не існує. Використовуйте .замість цього.
Мелле

18

Інший варіант, який мені здається простішим, - це запустити скрипт за допомогою cron і сказати bash для входу (отже, використання /etc/profile.d/...визначень оточення)

У crontab -eфайлі:

*/1 * * * * bash -l -c './cron_job.sh'
*/1 * * * * bash -l -c 'php -f ./cron_job.php'

Будь-яка команда після джерела .bash_profileбуде мати ваше оточення, як ніби ви ввійшли в систему.


10

Погана ідея. Загальна практика полягає в тому, щоб спеціально встановити всі необхідні змінні середовища в сценарії, який повинен бути запущений із завдання cron.


Я погоджуюся з @fpmurphy, що таким чином він також забезпечує захищене середовище процесу. Якщо ви хочете встановити лише кілька змінних від cron, ви можете скористатися /usr/bin/envкомандою для встановлення змінних, а потім може діяти як середовище для процесу cronjob.
Nikhil Mulley


6
Я все для безпеки, але, можливо, я можу створити файл ~/.cronvarsі включити його в профіль, а також у свої сценарії cron. Я не хочу жорстко кодувати змінні середовища в кожному із запущених сценаріїв, тому що, коли шляхи змінюють жорсткі кодовані шляхи у кожному файлі, їх нелегко підтримувати. Схоже, це дозволило б централізовувати місце для необхідних змінних і все-таки запобігти завантаженню інших змінних.
cwd

4

Цей синтаксис вам точно допомагає. Я не розумію синтаксису, але він працює. Oracle використовує цей синтаксис, коли розгортає Oracle Configuration Manager на crontab, отже, я вважаю, що це правильне рішення.

0 5 * * * SOME_ENV_VAR=some_value some_command some_parameters

2

Нещодавно я натрапив на випадок, коли мені довелося виконати загальний cronjob як root, але, в той же час, довелося виконати підкоманду як іншого користувача (що вимагало пошуку середовища цього користувача). Я пішов із таким підходом:

# m  h  dom  mon  dow  user  command
*/5  *   *    *    *   root  (sudo -i -u <the user> command-to-be-run-as-user) && command-to-be-run-as-root

Найважливіша частина - це аргумент -i, який передається, і sudoякий буде виконувати дану команду в окремій оболонці входу (що, в свою чергу, означає, що точкові файли користувача будуть отримані).

PS: Зауважте, що userстовпець доступний лише у /etc/crontabта /etc/cron.d/*файлах.


1

Рішення, яке працювало для мене, як описано тут .

Ви створюєте сценарій обгортки, який дзвонить . ~/.cronfile, а потім виконує потрібні вам речі. Цей сценарій запускається cron.

У ~/.cronfileвас вказати умови для ваших хрон робочих місць.


1

Так, ви можете скористатися "добре відомими способами обходу" (кілька з них були перераховані). Це ще один спосіб сказати, що всі знають, що це хитро, хоча деякі люди називатимуть це "функцією безпеки", тому що вони витратили принаймні стільки ж, натрапляючи на цю невдачу (уре), як у вас, і хотіли б подумати про їх даремно витрачений час не даремно. Це хроновий еквівалент клавіатури QWERTY.

Я підозрюю, що первісна причина, можливо, була в продуктивності, так що сценарії, що працюють один раз на хвилину, не витрачали часу на читання сценаріїв. Також спочатку cron взагалі не був налаштований, тому за замовчуванням насправді було єдиним варіантом.

Немає додаткової безпеки, якщо немає простої конфігурації чи методу, щоб cron просто перейняв оточення вашої інтерактивної оболонки, а не користувачі повинні виконувати тупу гімнастику. На сучасному верстаті, як правило, не відчутний приріст продуктивності, якщо ви не маєте великої кількості робіт щохвилини.

Культура Unix провалюється. На мою скромну думку. :-)


1
"Немає додаткової безпеки." Це не правда. Погляньте на CVE-2011-1095 , CVE-2008-4304 та CVE-2010-3847 .

До речі, я відповів на вашу відповідь. Я, як правило, намагаюся уникати відповідей нових відповідей, але для мене важлива безпека. Будь ласка, не сприйміть протиправний шлях неправильно. Окрім частини про безпеку, ваша відповідь є чудовою і заслуговує на користь. Ви можете змінити свою відповідь тут, якщо хочете.

Жоден із них не має ні найменшого відношення до того, щоб cron використовував оболонку із встановленим інтерактивним прапором. Це чистий FUD. На жаль, я не можу відмовитись від вашого права. Це може здатися полум'ям, але це дуже засмучує, коли люди думають, що транспортний засіб з трьома колесами є кращим, тому що питання безпеки має поставити четверте колесо. Це не так. Люди так довго їхали на триколісному велосипеді, що забули, що можна додати четверте колесо.
Остін С.

По-іншому: якщо використовуються будь-які із запропонованих додаткових обручів, запропоновані іншими відповідями, то як вони також не отримають доступ до жодної з названих вами дірок? "* * * * * exec bash -i -c LOCALE = ......."
Austin S.

Це читається, як тираж. Я навіть не бачу, де це взагалі відповідає на питання. Навіть якби частина безпеки була видалена, @EvanTeitelman, я не бачу, чому вона заслужила б надмірного платежу, оскільки вона не відповідає на питання.
Wildcard


1

Замість того, щоб налаштувати профіль, мені допомогло налаштування PATH. Деякі команди не були доступні в моїх сценаріях cron, оскільки вони PATHрізні.

ENVIRONMENT=prod
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
*/30 * * * * /opt/myscript1.sh
*/30 * * * * /opt/myscript2.sh
*/30 * * * * /opt/myscript3.sh

Постановка PATHз маршрутом команд мені допомогла. Ще краще, якщо ви зможете скористатися шаблоном і детемплатизувати пізніше,

ENVIRONMENT={{ENVIRONMENT}}
PATH={{PATH}}
*/30 * * * * /opt/myscript1.sh
*/30 * * * * /opt/myscript2.sh
*/30 * * * * /opt/myscript3.sh

Передача змінних кожному елементу виглядає безладним.


-1

Я кладу . ~/.dbus/session-bus/*вгорі потрібного сценарію :)


1
Ласкаво просимо в U & L SE. Будь ласка, розгорніть свою відповідь більше, щоб вона принесла користь читачам.
Рамеш
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.