crontab ПУТЬ и ПОЛЬЗОВАТЕЛЬ

Я новичок в планировании задач с помощью cron и crontab. Я пытаюсь запланировать выполнение задачи, как если бы я вошел в систему, открыл терминал и выполнил его сам.

Однако я запланировал задачу, чтобы помочь мне наблюдать, с какими $ USER и $ PATH выполняется запланированная задача, и вот что я обнаружил:

$ crontab -l
41 11 * * * echo "USER: $USER" > ~/Desktop/cron_env.log; echo "PATH: $PATH" >> ~/Desktop/cron_env.log
$ cat ~/Desktop/cron_env.log
USER:
PATH: /usr/bin:/bin

Похоже, что $ USER не установлен, а $ PATH - это что-то очень простое и / или по умолчанию. Напротив, это то, что я вижу, когда открываю терминал (вошел в систему) и повторяю ту же информацию:

USER: aschirma
PATH: /usr/lib/jvm/java-6-sun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/pkg/icetools/bin:/pkg/hwtools/bin:/pkg/netscape/bin:/pkg/gnu/bin

Что мне нужно сделать, чтобы мои задачи crontab работали так, как я хочу?


person Adam S    schedule 12.04.2012    source источник


Ответы (5)


Согласно "man 5 crontab" вы можете установить переменные среды в вашем crontab, написав их перед строками cron.

Также есть пример crontab, поэтому вам просто нужно скопировать / вставить его:

$ man 5 crontab | grep -C5 PATH | tail 
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow usercommand
17 * * * *  root  cd / && run-parts --report /etc/cron.hourly
25 6 * * *  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )

Таким образом, вы можете настроить свой PATH или любую переменную среды по своему усмотрению. Но для типичных случаев этого примера вполне достаточно.

person Julien Palard    schedule 04.02.2013
comment
Есть ли способ сделать что-то вроде PATH=$PATH:/usr/local/bin? - person CMCDragonkai; 29.11.2015
comment
@CMCDragonkai: Согласно man 5 crontab, строка значения не анализируется на предмет подстановки окружения или замены переменных. Но вам, вероятно, следует написать код в одном исполняемом файле (обычно .sh, но почему бы не C ou Python?), Вызвать свой исполняемый файл из crontab и позволить исполняемому файлу самим увеличивать свой $ PATH. - person Julien Palard; 01.12.2015
comment
Это решило сообщество . letsencrypt.org/t/ для меня. - person Björn; 30.01.2017
comment
TIL о man 5, см. unix.stackexchange.com/questions/3586/ для получения полного объяснения". - person James McMahon; 14.03.2019
comment
FWIW, crontab(5) из cronie не упоминает PATH переменная явно, но вместо этого указывает An active line in a crontab is either an environment setting or a cron command, поэтому здесь поддерживается любая переменная среды (включая PATH. - person ckujau; 25.03.2021

В * ix процессы обычно наследуют среду от своего родительского процесса через fork + exec. У них есть возможность очистить окружающую среду, но обычно они этого не делают. Вы можете увидеть дерево процессов с помощью ps axf, и вы можете увидеть переменные среды с помощью ps axfe.

cron обычно не является потомком чьей-либо оболочки, поэтому его среда часто отличается от среды вашей интерактивной оболочки. Однако есть большая вероятность, что cron намеренно очистит свою среду каким-то образом для согласованности.

Мне нравится тестировать свои задания cron ("foo" для обсуждения) с помощью следующего в интерактивной оболочке: env - ./foo Это на самом деле очистит больше переменных env, чем cron, но облегчит получение вещей иду ИМО, так как то, что вы тестируете, более похоже. Вам нужно будет установить любые переменные, от которых вы зависите (например, $ PATH), или заменить их чем-то другим - например, $ USER становится $ (whoami).

Я также люблю писать свои сценарии bash, чтобы использовать "set -eu" и "set -o pipefail". -Eu говорит «выйти при ненулевом коде выхода и выйти при неопределенной ссылке на переменную», а pipefail говорит: «не возвращать последний код выхода в конвейере, вместо этого возвращать первый код выхода, который не равен нулю в конвейере». . В вашем случае набор -u может быть особенно полезен.

person user1277476    schedule 12.04.2012
comment
+1 для тестирования ... Я man env хотел бы найти информацию о единственном тире. Я бы хотел, чтобы он был включен в строку -i, --ignore-environment, а не в конец раздела описания, где я полностью его замалчил. - person Dale Anderson; 14.09.2015

Помните, что crontab - это демон или служба, поэтому он не похож на пользователя, вошедшего в систему или что-то в этом роде. Если вы хотите иметь переменные среды, вам нужно будет установить их самостоятельно. Однако большинство этих переменных задаются оболочкой из пути / etc / profile, а затем переходят в ваши пользовательские переменные в каталог $ HOME.

Вы можете установить некоторые из них, "указав источник" в вашем / etc / profile, например:

41 11 * * * /home/<me>/cron_env.sh
Где cron_env.sh будет содержать что-то вроде:
#!/bin/sh
source /etc/profile
/usr/bin/env > /home/<me>/cron_env.log

person Freddy    schedule 12.04.2012
comment
Все вышеперечисленное у меня не сработало, поэтому я просто добавил Source в свой файл bash, и он сработал! Спасибо - person Murtaza Kanchwala; 01.09.2016

В нашей среде у нас обычно нет этой проблемы, поскольку root - единственный разрешенный cron, и каждая команда обычно запускается от имени конкретного пользователя приложения через команду su -c как:

su - myuser -c "/usr/local/scripts/app.sh" 2>&1

поскольку указана опция «-», мы получаем профиль и среду myuser. Недавно у нас возникла проблема с командой, для успешного завершения которой требовались права root, поэтому мы просто выполнили команду без su -c. После некоторого количества исследований нас осенило, что самый простой способ получить среду root - это использовать ту же технику для root, что и для всех других приложений, поэтому мы выпустили:

su - root -c "/usr/local/scripts/app.sh" 2>&1
person Alan Kwiatkowski    schedule 29.07.2015

crontab не является сценарием bash, вы не можете использовать переменные среды, которые обычно доступны в оболочке.

Попробуйте переместить весь этот код в файл сценария с шебангом (который начинается со строки "#! / Bin / bash") и запустить этот сценарий в crontab.

Я не уверен, но я думаю, что PATH (и, возможно, EMAIL, если вы его установите) может быть единственным, к которому вы можете получить доступ внутри файла crontab.

РЕДАКТИРОВАТЬ: проверьте справочную страницу crontab 5, доступно довольно много переменных среды, и все они устанавливаются демоном cron.

person KurzedMetal    schedule 12.04.2012
comment
ОП здесь. Скрипты, запущенные из cron, не наследуют правильный PATH. Фактически, именно здесь я впервые начал сталкиваться с проблемами: сценарий bash, выполняемый из cron, не находил что-либо в PATH, потому что PATH был неправильным. - person Adam S; 12.04.2012
comment
@AdamS В этом проблема, они наследуют PATH (и несколько других переменных), заданный демоном cron, который отличается от того, что вы получаете из оболочки входа в систему, вы можете установить PATH в своем файле crontab, если хотите. - person KurzedMetal; 12.04.2012
comment
На странице руководства: The value string is not parsed for environmental substitutions or replacement of variables, thus lines like PATH = $HOME/bin:$PATH will not work as you might expect. - person ; 14.10.2015