CRON이 올바른 PATH를 호출하도록하는 방법


124

cron이 올바른 PATH를 호출하도록하려고합니다. 쉘에서 Python 스크립트를 실행하면 bashrc에 설정된 PATH를 사용하므로 스크립트가 잘 실행되지만 cron을 사용할 때 모든 PATH는 bashrc에서 사용되지 않습니다. bashrc와 같은 cron에 대한 PATH를 입력 할 수있는 파일이나 bashrc에서 PATH를 호출하는 방법이 있습니까?

죄송합니다. 내가 올바르게 말한 것 같지 않습니다. 올바른 스크립트를 실행할 수 있습니다 (크론 탭의 스크립트에 대한 PATH가 여기서 문제가되지 않음을 의미합니다). 그 스크립트가 실행 중일 때 빌드를 실행하고 이것은 경로의 설정 .bashrc. 로그인 할 때 스크립트를 실행하면 .bashrcPATH가 풀인됩니다 .bashrc. cron은 쉘에서 실행되지 않기 때문에 . bash 스크립트 래퍼를 작성할 필요없이 이것을 끌어 오는 방법이 있습니까?


또한 cronjobs에서 작동하도록 bashrc 설정을 얻는 방법에 대한 여기에 제공된 제안을 살펴보십시오. stackoverflow.com/q/15557777/1025391
moooeeeep

2
현재 환경에 프로필을 포함시키는 마법의 간단하고 올바른 명령은 다음 source /etc/profile과 같습니다. 그것은 .bashrc당신을 위해 잠재적으로 놓칠 수있는 다른 많은 것들을 먹어야 합니다. 명시 적 프로필 소싱은 일부 스크립트를 "독립 실행 형"으로 실행하려는 경우 매우 유용합니다. 또한 이상한 환경으로부터 보호합니다.
exa

1
@exa +100 이렇게하면 shcrontab에서 호출하는 스크립트가 작동합니다. 같은 작업을 추가하고 * * * * * echo $PATH > ~/crontab_path.txt1 분 후에 파일을 확인하여 경로가 업데이트되었는지 확인할 수 있습니다 .
geotheory

답변:


177

나는 /etc/crontab. vi이 파일에 필요한 PATH를 사용 하고 입력하고 루트로 실행했습니다. 일반 crontab은 설정 한 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와 함께 작동하며 그 방법도 더 안전합니다.
Robert Brisita 2013 년

2
sh 대신 bash를 사용할 수 있습니까?
qed nov.

1
@chrissygormley에 의해 표시되고 내 (Ubuntu) crontab에 설정된 기본 경로가 / etc / crontab에 설정된 기본 경로가 / etc / environment의 경로와 다르며 특히 / sbin 및 / bin은 / usr / sbin 및 / usr / bin보다 앞서 있습니다. 나는 이제 이것을 사용자 환경과 동일하게 만들기 위해 / etc / crontab에서 변경했습니다.
scoobydoo

나를 위해 작동하지 않습니다 .. cron 콘텐츠를 파일로 출력하고 있습니다. Cron이 실행되고 파일이 생성되지만 내용을 넣지 않습니다.
Volatil3

2
/etc/crontabUbuntu 14.04에서 루트로 실행할 때 cron에 설정된 모든 경로 를 사용할 수 있는 것은 아닙니다 . ( sudo crontab -e)
David Oliver

50

대부분의 경우 cron은 매우 드문 환경에서 실행됩니다. 다음 env과 같이 파일에 덤프하는 더미 작업을 추가하여 cron이 사용하는 환경 변수를 확인하십시오 .

* * * * * 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의 답변과 유사하며 crontab 규칙 앞에 PATH가 정의되어 있습니다.


22

당신은 당신의 crontab. 이것이 가장 안전한 옵션입니다.
그렇게하고 싶지 않다면 프로그램 주위에 래퍼 스크립트를 넣고 거기에 PATH를 설정할 수 있습니다.

예 :

01 01 * * * command

된다 :

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

또한에서 호출되는 모든 cron것은 실행되는 프로그램에 대해 매우주의해야하며 아마도 PATH변수에 대한 자체 선택을 설정해야 합니다.

편집하다:

which <command>쉘에서 실행하려는 명령의 위치를 ​​모르는 경우 경로를 알려줍니다.

EDIT2 :

따라서 프로그램이 실행되면 가장 먼저해야 할 일은 스크립트를 실행하는 데 필요한 값 으로 설정 PATH하고 다른 필수 변수 (예 LD_LIBRARY_PATH:)를 설정하는 것입니다.
기본적으로 프로그램 / 스크립트에 더 적합하도록 크론 환경을 수정하는 방법을 생각하는 대신 스크립트가 시작될 때 적절한 환경을 설정하여 주어진 환경을 처리하도록합니다.


1
경로에서 'which command'를 사용하면 전체 경로가 제공됩니다
Paul Whelan

@Douglas Leeder-전체 경로를 cron에 넣으라고 할 때 crontab이나 다른 파일에 넣으라는 뜻입니까? cron 명령이 '01 01 * * * command '이면 어떻게 하시겠습니까? 감사합니다
chrissygormley 2010 년

@chrissygormley-예 crontab.
Douglas Leeder

혼란스러워서 죄송합니다. 위의 질문을 변경했습니다.
chrissygormley 2010 년

16

내 crontab의 명령 줄 바로 앞에 PATH 설정이 효과적이었습니다.

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

이 방법을 선호합니다. 또는 스크립트의 전체 경로를 지정하십시오.
zw963 2017-04-13

5
나는 경로가 계속 성장할 것이라고 생각하지 않습니다. 매번 새로운 환경이 실행될 때마다 PATH의 새로운 사본이 있습니다.
jjcf89

@ jjcf89가 올바른지 확인할 수 있으며 PATH는 실행할 때마다 새로워집니다.
electrovir

14

올바른 값으로 사용자 crontab에 PATH 정의를 추가하면 도움이 될 것입니다 ... 저는 다음과 같이 채웠습니다.

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

그리고 모든 스크립트가 작동하도록하는 것으로 충분합니다. 필요한 경우 사용자 지정 경로를 포함합니다.


1
사용자 crontab의 경우 이것이 정답이어야합니다. 시스템의 모든 사람이 편집 할 수있는 것은 아닙니다 /etc/crontab. 이것은 사용자 수준에서 가장 쉬운 대답입니다. @ Treviño 잘 했어. 동의하면 투표하십시오.
frederickjh

14

당신의 변수가 당신을 위해 작동하도록 만드십시오.

/etc/profile.d/*.sh에 PATH를 정의하십시오.

시스템 전체 환경 변수

/etc/profile.d 디렉토리에있는 .sh 확장자를 가진 파일은 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

11

문제

스크립트는 콘솔에서 실행할 때 작동하지만 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 예제 출력


3

내 AIX cron에서 .profile에 설정된 내용을 무시하고 / etc / environment에서 환경 변수를 선택합니다.

편집 : 또한 다양한 연령대의 Linux 상자 몇 개를 확인했는데이 파일에도이 파일이있는 것으로 보이므로 AIX에만 국한되지 않을 수 있습니다.

joemaller의 cron 제안을 사용하여 이것을 확인하고 / etc / environment에서 PATH 변수를 편집하기 전후에 출력을 확인했습니다.


3

여러 위치에서 동일한 편집을 수행하지 않으려면 대략 다음과 같이하십시오.

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

. bashrc의 경로와 && 명령은 실행중인 bash 쉘에 환경 변경을 가져 오는 마법입니다. 또한 셸이 bash가되도록하려면 crontab에 다음 줄을 추가하는 것이 좋습니다.

SHELL=/bin/bash

누군가에게 도움이되기를 바랍니다!


2

cron 작업의 기본 환경은 매우 드물고 Python 스크립트를 개발하는 환경과 매우 다를 수 있습니다. cron에서 실행될 수있는 스크립트의 경우 의존하는 모든 환경을 명시 적으로 설정해야합니다. cron 파일 자체에 python 실행 파일과 python 스크립트에 대한 전체 경로를 포함합니다.


2

나는 이것이 이미 답을 얻었음을 알고 있지만 그의 것이 일부에게 유용 할 것이라고 생각했습니다. 최근에 해결 한 비슷한 문제가 있는데 ( 여기에서 찾을 수 있음 )이 질문에 답하기 위해 취한 단계의 주요 내용은 다음과 같습니다.

  1. 스크립트가 작동하는지 테스트하려는 셸의 .profile 또는 .bash_profile 내부에 PYTHONPATH (여기와 여기 및 여기에 자세한 정보가 있음)에 필요한 변수가 있는지 확인하십시오.

  2. cron 작업에서 스크립트를 실행하는 데 필요한 디렉토리를 포함하도록 crontab을 편집하십시오 (여기 및 여기에 있음).

    a) 여기에 설명 된대로 PATH 변수 (.)에 루트 디렉터리를 포함해야합니다 (기본적으로 명령으로 실행 파일을 실행하는 경우 루트 또는 실행 파일이 저장된 디렉터리를 찾을 수 있어야 함). (/ sbin : / bin : / usr / sbin : / usr / bin)

  3. crontab 파일에서 이전에 스크립트를 성공적으로 실행 한 디렉토리 (예 : Users / user / Documents / foo)로 디렉토리를 변경하는 cronjob을 만듭니다.

    a) 다음과 같이 표시됩니다.

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

2

@Trevino : 귀하의 답변은 제 문제를 해결하는 데 도움이되었습니다. 그러나 초보자는 단계별 접근 방식을 시도합니다.

  1. 다음을 통해 Java의 현재 설치를 가져옵니다. $ echo $JAVA_HOME
  2. $ crontab -e
  3. * * * * * echo $PATH-현재 crontab에서 사용하는 PATH 값을 이해할 수 있습니다. crontab을 실행하고 crontab에서 사용하는 $ PATH 값을 가져옵니다.
  4. 이제 crontab을 다시 편집하여 원하는 Java bin 경로를 설정하십시오. a) crontab -e; b) PATH=<value of $JAVA_HOME>/bin:/usr/bin:/bin(샘플 경로) c) 이제 예약 된 작업 / 스크립트는 다음과 같습니다 */10 * * * * sh runMyJob.sh &. d) 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루트 사용자로 호출 하고 로그인 한 것처럼 설정된 $ PATH를 포함하여 사용자의 전체 환경에서 셸을 시작합니다. 다른 배포판에서 동일하게 작동하며 .bashrc를 소싱하는 것보다 더 안정적입니다. me) 예제 또는 설정 도구를 제공하고 사용자 시스템의 배포판 또는 파일 레이아웃을 모르는 경우 문제가 될 수있는 특정 경로를 하드 코딩하지 않습니다.

su루트가 아닌 다른 사용자를 원할 경우 사용자 이름을 지정할 수도 있지만 지정하는 사용자로 전환 할 수있는 충분한 권한 이 있는지 확인 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.