it-swarm.com.ru

Как заставить CRON звонить в правильные пути

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

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

104
chrissygormley

Я использовал /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
146
chrissygormley

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

* * * * * env > env_dump.txt

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

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

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

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

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

45
joemaller

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

например.

01 01 * * * command

будет выглядеть так:

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

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

Правка:

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

EDIT2:

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

19
Douglas Leeder

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

Определите свой 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
14
Artistan

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

* * * * * PATH=$PATH:/usr/local/bin:/path/to/some/thing
13
myrho

Проблема

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

Причина

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

Решение

Добавьте вашу текущую оболочку и укажите путь к 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

9
brakertech

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

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

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

9
Treviño

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

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

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

2
Van Amburg

Среда по умолчанию для заданий cron очень скудна и может сильно отличаться от среды, в которой вы разрабатываете свои сценарии python. Для сценария, который может быть запущен в cron, любая среда, от которой вы зависите, должна быть установлена ​​явно. В самом файле cron укажите полные пути к исполняемым файлам python и вашим скриптам python.

2
mob

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

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

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

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

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

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

    * * * * cd /Users/user/Documents/foo; bar -l doSomething -v 
    
2
derigible

@Trevino: ваш ответ помог мне решить мою проблему. Однако для новичка стараюсь дать пошаговый подход. 

  1. Получите текущую установку Java через $ echo $Java_HOME
  2. $ crontab -e
  3. * * * * * echo $PATH - это позволяет понять, какое значение PATH используется crontab в настоящее время. Запустите crontab и получите значение $ PATH, используемое crontab.
  4. Теперь снова отредактируйте crontab, чтобы установить желаемый путь к бину Java: a) crontab -e; б) PATH=<value of $Java_HOME>/bin:/usr/bin:/bin (примерный путь); в) теперь ваша запланированная работа/сценарий, как */10 * * * * sh runMyJob.sh &; d) удалите echo $PATH из crontab, так как он сейчас не нужен.
1
Ram Dwivedi

Самый простой обходной путь, который я нашел, выглядит следующим образом:

* * * * * root su -l -c command

В этом примере вызывается su от имени пользователя root и запускается командная консоль с полной средой пользователя, включая $ PATH, настроенной так, как будто они вошли в систему. Он работает одинаково на разных дистрибутивах, более надежен, чем sourcing .bashrc (который не работал для меня) и избегает жесткого кодирования определенных путей, что может быть проблемой, если вы предоставляете пример или инструмент установки и не знаете, какой дистрибутив или макет файла в системе пользователя.

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

1
tasket

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

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

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

Shell=/bin/bash

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

1
Wade Chandler

Установите необходимый путь в вашем cron 

crontab -e

Правка: Нажмите i

PATH=/usr/local/bin:/usr/local/:or_whatever

10 * * * * your_command

Сохраните и выйдите из :wq

0
shiva