Как заставить CRON звонить в правильные пути - PullRequest
109 голосов
/ 05 марта 2010

Я пытаюсь заставить cron вызывать правильные PATH.Когда я запускаю скрипт Python из оболочки, он работает нормально, так как он использует PATH, установленные в bashrc, но когда я использую cron, все PATH не используются из bashrc.Есть ли файл, в который я могу ввести PATH для cron, например bashrc, или способ вызова PATH из bashrc?

Извините, я не думаю, что сформулировал это правильно, я могу запустить правильный скрипт (это означает, что путь PATH к сценарию в crontab не является проблемой), просто когда этот сценарий запущен, я запускаю сборку, которая использует значения PATH, установленные в .bashrc.Когда я запускаю скрипт, когда я вхожу в систему, .bashrc PATH извлекаются. Так как cron не запускается в оболочке, скажем, он не извлекает .bashrc.Есть ли способ сделать это без написания оболочки-сценария bash?

Ответы [ 15 ]

154 голосов
/ 09 марта 2010

Я использовал /etc/crontab. Я использовал vi и ввел необходимые мне PATH в этот файл и запустил его как root. Обычный crontab перезаписывает установленные вами пути. Хороший учебник о том, как это сделать .

Общесистемный файл cron выглядит так:

This has the username field, as used by /etc/crontab.
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file.
# This file also has a username field, 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 user   command
42 6 * * *   root    run-parts --report /etc/cron.daily
47 6 * * 7   root    run-parts --report /etc/cron.weekly
52 6 1 * *   root    run-parts --report /etc/cron.monthly
01 01 * * 1-5 root python /path/to/file.py
46 голосов
/ 22 июня 2012

Скорее всего, cron работает в очень редкой среде.Проверьте переменные среды, которые использует cron, добавив фиктивное задание, которое создает дамп env в файл, подобный следующему:

* * * * * env > env_dump.txt

Сравните это с выводом env в обычном сеансе оболочки.

Вы можете добавить свои собственные переменные окружения к локальному crontab, определив их в верхней части вашего crontab.

Вот быстрое исправление, добавляющее $PATH к текущему crontab:

# echo PATH=$PATH > tmp.cron
# echo >> tmp.cron
# crontab -l >> tmp.cron
# crontab tmp.cron

Полученный crontab будет выглядеть аналогично ответу chrissygormley с PATH, определенным до правил crontab.

20 голосов
/ 05 марта 2010

Вы должны указать полный путь в вашем crontab.Это самый безопасный вариант.
Если вы не хотите этого делать, вы можете поместить в свои программы скрипт-обертку и установить туда PATH.

например,

01 01 * * * command

становится:

01 01 * * * /full/path/to/command

Кроме того, все, что вызывается из cron, должно быть очень осторожным с программами, которые оно запускает, и, вероятно, установить свой собственный выбор для переменной PATH.

EDIT:

Если вы не знаете, где находится команда, которую вы хотите выполнить which <command> из вашей оболочки, и она укажет вам путь.

EDIT2:

Таким образом, после запуска вашей программы первое, что она должна сделать, - установить PATH и любую другую обязательную переменную (например, LD_LIBRARY_PATH) на значения, необходимые длясценарий для запуска.
По сути, вместо того, чтобы думать, как изменить среду cron, чтобы сделать ее более подходящей для вашей программы / сценария - заставьте ваш сценарий обрабатывать заданную среду, задавая соответствующую при запуске.

14 голосов
/ 03 октября 2014

Сделайте так, чтобы ваши переменные работали на вас, это позволит получить доступ к

Определите свой PATH в /etc/profile.d/*.sh

Общесистемные переменные среды

Файлы с расширением .sh в каталоге /etc/profile.d выполняются при каждом входе в оболочку bash (например, при входе из консоли или через ssh), а также DisplayManager при сеансе рабочего стола грузы.

Например, вы можете создать файл /etc/profile.d/myenvvars.sh и установить переменные следующим образом:

export JAVA_HOME=/usr/lib/jvm/jdk1.7.0
export PATH=$PATH:$JAVA_HOME/bin

Выполнить crontab с опцией входа в систему!

Сценарий или команда запуска CRONTAB с переменными среды

0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c 'php -f ./download.php'
0 9 * * * cd /var/www/vhosts/foo/crons/; bash -l -c download.sh
13 голосов
/ 15 апреля 2014

Установка PATH непосредственно перед тем, как у меня сработала командная строка в моем crontab:

* * * * * PATH=$PATH:/usr/local/bin:/path/to/some/thing
11 голосов
/ 23 августа 2013

Задача

Ваш скрипт работает, когда вы запускаете его из консоли, но не работает в cron.

Причина

Ваш crontab не имеет правильных переменных пути (и, возможно, оболочки)

Решение

Добавьте вашу текущую оболочку и укажите путь к crontab

Скрипт, который сделает это за вас

#!/bin/bash
#
# Date: August 22, 2013
# Author: Steve Stonebraker
# File: add_current_shell_and_path_to_crontab.sh
# Description: Add current user's shell and path to crontab
# Source: http://brakertech.com/add-current-path-to-crontab
# Github: hhttps://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_shell_and_path_to_crontab.sh

# function that is called when the script exits (cleans up our tmp.cron file)
function finish { [ -e "tmp.cron" ] && rm tmp.cron; }

#whenver the script exits call the function "finish"
trap finish EXIT

########################################
# pretty printing functions
function print_status { echo -e "\x1B[01;34m[*]\x1B[0m $1"; }
function print_good { echo -e "\x1B[01;32m[*]\x1B[0m $1"; }
function print_error { echo -e "\x1B[01;31m[*]\x1B[0m $1"; }
function print_notification { echo -e "\x1B[01;33m[*]\x1B[0m $1"; }
function printline { 
  hr=-------------------------------------------------------------------------------------------------------------------------------
  printf '%s\n' "${hr:0:${COLUMNS:-$(tput cols)}}"
}
####################################
# print message and exit program
function die { print_error "$1"; exit 1; }

####################################
# user must have at least one job in their crontab
function require_gt1_user_crontab_job {
        crontab -l &> /dev/null
        [ $? -ne 0 ] && die "Script requires you have at least one user crontab job!"
}


####################################
# Add current shell and path to user's crontab
function add_shell_path_to_crontab {
    #print info about what's being added
    print_notification "Current SHELL: ${SHELL}"
    print_notification "Current PATH: ${PATH}"

    #Add current shell and path to crontab
    print_status "Adding current SHELL and PATH to crontab \nold crontab:"

    printline; crontab -l; printline

    #keep old comments but start new crontab file
    crontab -l | grep "^#" > tmp.cron

    #Add our current shell and path to the new crontab file
    echo -e "SHELL=${SHELL}\nPATH=${PATH}\n" >> tmp.cron 

    #Add old crontab entries but ignore comments or any shell or path statements
    crontab -l | grep -v "^#" | grep -v "SHELL" | grep -v "PATH" >> tmp.cron

    #load up the new crontab we just created
    crontab tmp.cron

    #Display new crontab
    print_good "New crontab:"
    printline; crontab -l; printline
}

require_gt1_user_crontab_job
add_shell_path_to_crontab

Источник

https://github.com/ssstonebraker/braker-scripts/blob/master/working-scripts/add_current_shell_and_path_to_crontab.sh

Пример вывода

add_curent_shell_and_path_to_crontab.sh example output

10 голосов
/ 30 ноября 2013

Добавление определения PATH в пользовательский crontab с правильными значениями поможет ... Я наполнил свой только:

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

И этого достаточно, чтобы все мои скрипты работали ... Включите любой пользовательский путь, если вам нужно.

3 голосов
/ 18 марта 2013

В моем AIX cron берет переменные окружения из / etc / environment, игнорируя то, что установлено в .profile.

Редактировать: Я также проверил пару коробок Linux разных возрастов, и у них, похоже, также есть этот файл, так что это, вероятно, не специфично для AIX.

Я проверил это с помощью предложения cron от joemaller и проверил вывод до и после редактирования переменной PATH в /etc/environment.

2 голосов
/ 22 июля 2013

Если вы не хотите вносить одинаковые правки в разных местах, то примерно так:

* * * * * . /home/username/.bashrc && yourcommand all of your args

. пробел, а затем путь к .bashrc и команда && - это магия, позволяющая внести изменения среды в работающую оболочку bash. Кроме того, если вы действительно хотите, чтобы оболочка была bash, хорошей идеей будет иметь строку в вашем crontab:

SHELL=/bin/bash

Надеюсь, это кому-нибудь поможет!

2 голосов
/ 17 июля 2013

Я знаю, что на этот вопрос уже дан ответ, но я подумал, что он будет полезен для некоторых.У меня была похожая проблема, которую я недавно решил ( найдено здесь ), и вот основные шаги, которые я предпринял, чтобы ответить на этот вопрос:

  1. убедитесь, что выесть переменные, которые вам нужны в PYTHONPATH (найдены здесь и здесь, и для получения дополнительной информации здесь) внутри .profile или .bash_profile для любой оболочки, в которой вы хотите протестировать ваш скрипт, чтобы убедиться, что он работает.

  2. отредактируйте ваш crontab, включив в него каталоги, необходимые для запуска вашего скрипта в задании cron (см. Здесь и здесь)

    a) обязательно включите корневой каталог в переменную PATH (.), Как описано здесь(в основном, если вы запускаете исполняемый файл с вашей командой, он должен быть в состоянии найти root или каталог, в котором хранится исполняемый файл) и, вероятно, они (/ sbin: / bin: / usr / sbin: / usr / bin)

  3. в вашем файле crontab создайте cronjob, который изменит каталог на каталог, в котором вы ранее успешно выполняли скрипт (т.е. Users / user / Documents / foo)

    а) Это будет выглядеть следующим образом:

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...