Як змусити CRON зателефонувати у правильних PATH


124

Я намагаюся отримати cron, щоб зателефонувати у правильні ПАТИ. Коли я запускаю скрипт Python з оболонки, сценарій працює нормально, оскільки він використовує встановлені в bashrc PATH, але коли я використовую cron, всі PATH не використовуються з bashrc. Чи є файл, в який я можу ввести PATHs для cron, як bashrc, або спосіб викликати PATHs від bashrc?

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


також поглянути на пропозицію Наведені тут про те , як отримати налаштування Bashrc для роботи cronjobs: stackoverflow.com/q/15557777/1025391
moooeeeep

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

1
@exa +100 Це робить shсценарії, викликані роботою crontab. Ви можете підтвердити оновлення контуру, додавши завдання на зразок * * * * * echo $PATH > ~/crontab_path.txtта перевіривши файл через хвилину.
геотеорія

Відповіді:


177

Я звик /etc/crontab. Я використовував viі вводив потрібні мені PATH-файли в цей файл і запускав його як root. Нормальна кротограма замінює налаштовані вами PATH. Хороший підручник про те, як це зробити .

Загальносистемний файл 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

17
Це працює з crontab -e на рівні користувача, і так безпечніше.
Роберт Брізіта

2
Чи можна використовувати bash замість sh?
qed

1
дивно (мені), що PATH за замовчуванням, встановлений у / etc / crontab, як показано на @chrissygormley, а також встановлений у моїй (Ubuntu) crontab, відрізняється від шляху в / etc / environment, зокрема він ставить / sbin і / bin попереду / usr / sbin та / usr / bin. Тепер я змінив це в моєму / etc / crontab, щоб зробити його таким же, як у середовищі користувачів.
Scoobydoo

Не працює для мене .. Я вивожу вміст cron у файл. Cron працює, файл створює, але він не додає до нього жодного вмісту.
Volatil3

2
Схоже, що не всі встановлені шляхи /etc/crontabдоступні для cron при запуску як root в Ubuntu 14.04. ( sudo crontab -e)
Девід Олівер

50

Швидше за все, 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.


22

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

напр

01 01 * * * command

стає:

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

Крім того, все, що викликається, cronповинно бути дуже уважним щодо програм, які він запускає, і, ймовірно, встановлює свій вибір для PATHзмінної.

Редагувати:

Якщо ви не знаєте, де знаходиться команда, яку потрібно виконати which <command>зі своєї оболонки, і вона підкаже вам шлях.

EDIT2:

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


1
якщо його на вашому шляху використовувати "яка команда", і це дасть вам повний шлях
Пол Уілан

@Douglas Leeder - Коли ти кажеш, що покласти повний шлях у cron, ти маєш на увазі помістити його в crontab чи інший файл? Якщо це так, як би ви зробили це, якщо команда cron: '01 01 * * * команда '. Спасибі
chrissygormley

@chrissygormley - Так crontab.
Дуглас Лідер

Вибачте, має бути певна плутанина. Я переформулював питання вище.
chrissygormley

16

Налаштування PATH перед тим, як командний рядок у моєму crontab працював на мене:

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

віддайте перевагу цьому способу. або вказати повний шлях сценарію.
zw963

5
Я не думаю, що шлях буде продовжувати зростати, щоразу, коли його пробіг буде новим середовищем, зі свіжою копією PATH ...
jjcf89

Може підтвердити, що @ jjcf89 вірно, PATH свіжий на кожному запуску.
електровірус

14

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

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

І цього достатньо, щоб усі мої сценарії працювали ... Включіть туди будь-який спеціальний шлях, якщо вам потрібно.


1
Для користувачів crontab це має бути правильною відповіддю. Не всі в системі можуть редагувати /etc/crontab. Це найпростіша відповідь на рівні користувача. Гарна робота @ Treviño. Проголосуйте за це, якщо ви згодні.
frederickjh

14

Зробіть, щоб ваші змінні працювали для вас, це дозволить отримати доступ t

Визначте свій PATH у /etc/profile.d/*.sh

Загальносистемні змінні середовища

Файли з розширенням .sh у каталозі /etc/profile.d виконуються щоразу, коли вводиться оболонка для входу в баш (наприклад, при вході з консолі або над 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

11

Проблема

Ваш сценарій працює, коли ви запускаєте його з консолі, але не працює в кроні.

Причина

Ваш 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


3

На моєму AIX Cron виявляє змінні середовища з / etc / Environment, ігноруючи те, що встановлено в .profile.

Редагувати: Я також перевірив кілька ящиків Linux різного віку, і, здається, у них є і цей файл, тому це, ймовірно, не є специфічним для AIX.

Я перевірив це, використовуючи пропозицію про cron joemaller і перевіряючи вихід до та після редагування змінної PATH у / etc / середовищі.


3

Якщо вам не потрібно вносити однакові зміни в різних місцях, то орієнтовно зробіть це:

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

The. простір, а потім шлях до .bashrc і команда && - це магія, щоб змінити ваше середовище в запущену оболонку bash. Занадто, якщо ви дійсно хочете, щоб оболонка була баш, це гарна ідея, щоб у вашому crontab була лінія:

SHELL=/bin/bash

Сподіваюся, це комусь допоможе!


2

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


2

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

  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 
    

2

@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 &; г) видалити echo $PATHз crontab, оскільки його зараз не потрібно.

2

Встановіть потрібний PATH у своєму кроні

crontab -e

Редагувати: Натисніть i

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

10 * * * * your_command

Збережіть і вийдіть :wq


1

Найпростіший спосіб пошуку, який я знайшов, виглядає так:

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

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

Ви також можете вказати ім'я користувача після того, suяк ви хочете іншого користувача, ніж root, але, ймовірно, слід залишити rootпараметр перед suкомандою, оскільки це забезпечує suдостатньо привілеїв для переходу на будь-якого вказаного вами користувача.


-3

Якщо ви користуєтесь webminцим, це такі кроки, як встановити PATHзначення:

System
  -> Scheduled Cron Jobs
       -> Create a new environment variable
            -> For user: <Select the user name>
            -> Variable name: PATH
            -> Value: /usr/bin:/bin:<your personal path>
            -> Add environment variable: Before all Cron jobs for user
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.