crontab에서 사용할 환경 변수를 어디에서 설정할 수 있습니까?


266

매시간마다 crontab을 실행하고 있습니다. .bash_profile사용자가 터미널에서 작업을 실행할 때 작동 하는 환경 변수가 있지만 사용자는 crontab에서 실행할 때 환경 변수를 선택하지 않습니다.

나는 그들을 설정 해봤 .profile하고 .bashrc있지만 여전히 발탁하지 않는 것. crontab이 가져올 수있는 환경 변수를 어디에 둘 수 있는지 아는 사람이 있습니까?

답변:


88

'cron'이 명령을 실행하기 전에 환경을 설정하는 쉘 스크립트를 실행하십시오.

항상.

#   @(#)$Id: crontab,v 4.2 2007/09/17 02:41:00 jleffler Exp $
#   Crontab file for Home Directory for Jonathan Leffler (JL)
#-----------------------------------------------------------------------------
#Min     Hour    Day     Month   Weekday Command
#-----------------------------------------------------------------------------
0        *       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/hourly
1        1       *       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/daily
23       1       *       *       1-5     /usr/bin/ksh /work1/jleffler/bin/Cron/weekday
2        3       *       *       0       /usr/bin/ksh /work1/jleffler/bin/Cron/weekly
21       3       1       *       *       /usr/bin/ksh /work1/jleffler/bin/Cron/monthly

~ / bin / Cron의 스크립트는 모두 다음과 같은 단일 스크립트 'runcron'에 대한 링크입니다.

:       "$Id: runcron.sh,v 2.1 2001/02/27 00:53:22 jleffler Exp $"
#
#       Commands to be performed by Cron (no debugging options)

#       Set environment -- not done by cron (usually switches HOME)
. $HOME/.cronfile

base=`basename $0`
cmd=${REAL_HOME:-/real/home}/bin/$base

if [ ! -x $cmd ]
then cmd=${HOME}/bin/$base
fi

exec $cmd ${@:+"$@"}

(오래된 코딩 표준을 사용하여 작성했습니다. 요즘에는 처음에 shebang '#!'을 사용합니다.)

'~ / .cronfile'은 엄청나게 비대화 형이며 시끄러운 소리를 내기 위해 cron에서 사용하는 프로파일의 변형입니다. 대신 .profile을 실행하도록 조정할 수 있습니다. (REAL_HOME 물건은 내 환경의 인공물입니다. $ HOME과 같은 척 할 수 있습니다.)

따라서이 코드는 적절한 환경을 읽은 다음 내 홈 디렉토리에서 비 크론 버전의 명령을 실행합니다. 예를 들어, '주중'명령은 다음과 같습니다.

:       "@(#)$Id: weekday.sh,v 1.10 2007/09/17 02:42:03 jleffler Exp $"
#
#       Commands to be done each weekday

# Update ICSCOPE
n.updics

'daily'명령이 더 간단합니다.

:       "@(#)$Id: daily.sh,v 1.5 1997/06/02 22:04:21 johnl Exp $"
#
#       Commands to be done daily

# Nothing -- most things are done on weekdays only

exit 0

246

crontab -e명령 행에서 실행할 때 crontab 자체에서 환경 변수를 정의 할 수 있습니다 .

LANG=nb_NO.UTF-8
LC_ALL=nb_NO.UTF-8
# m h  dom mon dow   command

* * * * * sleep 5s && echo "yo"

이 기능은 특정 cron 구현에서만 사용할 수 있습니다. 우분투와 데비안은 현재 vixie-cron 을 사용하는데,이를 crontab 파일 (GNU mcron )에 선언 할 수 있습니다 .

아치 리눅스레드햇 사용 cronie 하지 않는 환경 변수가 선언 될 수 있도록하고, cron.log에 구문 오류가 발생합니다. 해결 방법은 항목별로 수행 할 수 있습니다.

# m h  dom mon dow   command
* * * * * export LC_ALL=nb_NO.UTF-8; sleep 5s && echo "yo"

58
쉘에서와 같이 변수 대체를 사용할 수 없으므로 PATH = / usr / local / bin : $ PATH와 같은 선언은 문자 그대로 해석됩니다.
Zac

8
나는 RedHat 4.4.7-3과 cronie-1.4.4-15.el6.x86_64에서 crontab 자체에 환경 변수를 설정할 수있었습니다.
Bruno Lange

7
변수가 명령 내에서만 사용되는 경우 실제로 변수를 내보낼 필요가 없으며 명령 앞에 변수를 추가하십시오. "* * * * * 수면 5 초; LC_ALL = nb_NO.UTF-8 echo $ LC_ALL"
vutran


@BrunoLange 당신은 그들을 어떻게 설정 관리 pelase 공유 할 수 있습니까?
Newskooler 2019

145

이 문제에 대한 해결책이 하나 더 있습니다.

0 5 * * * . $HOME/.profile; /path/to/command/to/run

이 경우 $HOME/.profile파일에 정의 된 모든 환경 변수를 선택 합니다.

물론 $HOME설정되지 않은 경우 전체 경로로 바꿔야합니다 $HOME.


이것은 답변을 찾기 위해 많은 노력을 기울인 후에 저에게 효과적이었습니다. 감사합니다!
블라디미르 몬테 알레그레

5
$ HOME 이전의 기간을 제외하고 깨달을 때까지 이것은 작동하지 않았습니다. 그 기간은 정확히 무엇입니까?
flymike

9
마침표는 "source"명령과 같습니다. tldp.org/LDP/abs/html/special-chars.html#DOTREF
Jeff W

@PeterLee 언급 된 것이 당신을 위해 일했습니까? 위에서 언급 한 솔루션이 효과적이지 않기 때문에 이것을 썼습니다. 위에서 언급 한 해결책이 효과가 없다면 그 이유를 찾기 위해 약간의 연구를해야합니다. ;-)
Vishal

3
@Vishal 실제로, 그것은 이제 나를 위해 작동합니다. 나는 노력하고 있었고 source ~/.bashrc.bashrc파일이 크론 작업과 충돌 하는 것으로 판명되었습니다 . .env_setup_rc한 줄로 매우 간단한 파일을 사용 export MY_ENV_VAR=my_env_val하면 실제로 작동합니다. 내 게시물 참조 : stackoverflow.com/questions/15557777/…
Peter Lee

63

/etc/environment우분투 에서 vars를 설정하면 나를 위해 일했습니다. 12.04부터 /etc/environmentcron에 대한 변수 가로드됩니다.


11
가장 좋은 대답은 그냥 실행 env >> /etc/environment하면 CRON 작업에서 모든 현재 환경 변수를 사용할 수 있습니다.
Savageman

6
이것은 나를 위해 잘 작동합니다. 특히 Docker 컨테이너를 사용하고 있기 때문에 "시스템 전체"의 영향에 대해서는별로 신경 쓰지 않습니다.
Lucas Pottersky

14
융합 폭탄으로 파리를 죽이는 것과 같은 @Savageman은 예기치 않은 행동의 위험도 매우 높습니다.
Fran Marzoa

2
주의 : env >> /etc/environment환경 변수 중 하나에 해시 기호가 있으면 실패합니다. 내 응용 프로그램의 문제를 해결하는 데 가장 힘든 시간을 보냈습니다. 해당 단계에서 잘린 '#'이 포함 된 비밀번호 인 것으로 나타났습니다.
asac

3
이것이 정답입니다. 사람들이 왜 다른 답변이나 env >> / etc / environment에 관한이 질문을 복잡하게하는지 모르겠습니다. 이러한 환경 변수를 보편적으로 사용할 수있게하려면 etc / environment를 잘 깜박이십시오. 제 실험에서 / etc / environment의 환경 변수에 대한 내보내기 명령문이 crontab 및 사용자에게도 사용 가능한 것으로 확인되었습니다. 문제 : 다시 한 번 내 실험에서 :이 환경 변수는 crontab 자체에서 확장되지 않는 것 같습니다! ... 즉, 스크립트라는 스크립트에서만 확장됩니다!
마이크 설치류

39

스크립트를 시작하면 다음과 같이 cron을 통해 실행됩니다.

#!/bin/bash -l

그들은 ~/.bash_profile환경 변수를 선택해야합니다


4
이 답변은 더 많은 찬사를 받고 단순히 선택된 답변입니다. 매우 간단하고 우아하며 시스템 전체로 뛰어 넘을 필요가없는 수많은 kludges를 피하십시오.
JakeGould

나는이 답변 +1을 좋아한다. root의 crontab을 실행할 때 사용할 수 있습니까? /home/root시스템에 폴더 가 없으므로 root의 crontab에서 어떻게 작동하는지 알 수 없습니다 . 아이디어?
Seamus

스크립트 자체에서. 그런 다음 cron을 정상적으로 실행합니다.
breizhmg

@Jim 이 예제 는 클래식 실행 파일 (chmod 777)을 사용 #!/bin/bash합니다. 여기에 마법이 추가됩니다-l
Peter Krauss

22

내가 더 쉽게 찾은 @carestad 예제에서 확장하는 것은 cron으로 스크립트를 실행하고 스크립트에 환경을 두는 것입니다.

crontab -e 파일에서 :

SHELL=/bin/bash

*/1 * * * * $HOME/cron_job.sh

cron_job.sh 파일에서 :

#!/bin/bash
source $HOME/.bash_profile
some_other_cmd

.bash_profile의 소스 다음에 오는 모든 명령은 마치 로그인 한 것처럼 환경을 갖게됩니다.


16

나를 위해 PHP 응용 프로그램의 환경 변수를 설정해야했습니다. crontab에 다음 코드를 추가하여 다시 사랑했습니다.

$ sudo  crontab -e

크론 탭 :

ENVIRONMENT_VAR=production

* * * * * /home/deploy/my_app/cron/cron.doSomethingWonderful.php

doSomethingWonderful.php 내부에서 다음을 사용하여 환경 값을 얻을 수 있습니다.

<?php     
echo $_SERVER['ENVIRONMENT_VAR']; # => "production"

이게 도움이 되길 바란다!


이것은 나를 위해 작동하지 않았습니다. crontab 내에서 호출 된 스크립트에서 환경 변수를 사용할 수 없습니다.
Nikhil

12

설정 한 내용 crontab은 크론 작업에서 직접 사용할 수 있고 스크립트의 변수를 사용할 수 있습니다.

cronjob의 정의에 사용하십시오

crontabcronjob이 사용할 변수를 설정 하도록 구성 할 수 있습니다.

$ crontab -l
myvar="hi man"
* * * * * echo "$myvar. date is $(date)" >> /tmp/hello

이제 파일 /tmp/hello은 다음과 같은 것을 보여줍니다.

$ cat /tmp/hello 
hi man. date is Thu May 12 12:10:01 CEST 2016
hi man. date is Thu May 12 12:11:01 CEST 2016

cronjob이 실행하는 스크립트에서 사용하십시오.

crontab스크립트가 사용할 수있는 변수를 설정 하도록 구성 할 수 있습니다.

$ crontab -l
myvar="hi man"
* * * * * /bin/bash /tmp/myscript.sh

스크립트 /tmp/myscript.sh는 다음과 같습니다.

echo "Now is $(date). myvar=$myvar" >> /tmp/myoutput.res

다음을 /tmp/myoutput.res보여주는 파일 을 생성합니다 .

$ cat /tmp/myoutput.res
Now is Thu May 12 12:07:01 CEST 2016. myvar=hi man
Now is Thu May 12 12:08:01 CEST 2016. myvar=hi man
...

7

@Robert에서 확장 Brisita는 확장했습니다. 또한 스크립트에서 프로파일의 모든 변수를 설정하지 않으려는 경우 스크립트 상단에서 내보낼 변수를 선택할 수 있습니다

crontab -e 파일에서 :

SHELL=/bin/bash

*/1 * * * * /Path/to/script/script.sh

script.sh에서

#!/bin/bash
export JAVA_HOME=/path/to/jdk

some-other-command

7

대신에

0  *  *  *  *  sh /my/script.sh

bash -l -c 사용

0  *  *  *  *  bash -l -c 'sh /my/script.sh'

1
이유는 단지 파일의 상단에있는 배쉬 선언을하는 대신이를해야합니까 -l같은을 : #!/bin/bash -l? 이 다른 대답 은 간단하고 우아합니다.
JakeGould

1
bash가 아닌 perl / python / ruby ​​스크립트를 실행해야한다면 어떻게해야합니까? 파이썬 스크립트 맨 위에 #! / bin / bash -l을 추가 할 수 없습니다.
Ilya Kharlamov

"bash가 아닌 perl / python / ruby ​​스크립트를 실행해야한다면 어떻게해야합니까?" 그럴 수 있지. 그러나 내 마음 속에는 간단한 Bash 스크립트 래퍼를 작성하여 Python 스크립트를 호출 할 수 있습니다. PHP 스크립트에서도 비슷한 일을합니다. 프로세스 잠금은 Bash에서 훨씬 더 좋고 안정적이지만 Bash 스크립팅은 여전히 ​​두통입니다. 그래서 복잡한 것들을 PHP로 작성하고 Bash가 나머지를 처리하도록했습니다.
JakeGould

3

Oh-my-zsh맥북에서 사용 하고 있으므로 crontab 작업을 실행하기 위해 많은 것을 시도했지만 마침내 솔루션이 .zshrc명령을 실행하기 전에 앞에 덧붙였습니다 .

*/30 * * * * . $HOME/.zshrc; node /path/for/my_script.js

이 작업은 30 분마다 실행되며 .zshrc프로파일을 사용 하여 노드 명령을 실행합니다.

$HOMEvar 앞에 점을 사용하는 것을 잊지 마십시오 .


2

이 답변에서 영감을 얻은 변수를 "주입"하는 또 다른 방법 은 다음과 같습니다 (fcron 예제).

%daily 00 12 \
    set -a; \
    . /path/to/file/containing/vars; \
    set +a; \
    /path/to/script/using/vars

보낸 사람 help set:

-a 내보내기 위해 수정되거나 작성된 변수를 표시합니다.

-대신 +를 사용하면이 플래그가 꺼집니다.

모든 그래서 사이 set -set +도착에 수출 env하고 사용하지 않고 다른 스크립트 등을 위해 사용할 수있게됩니다 set공급받을 변수를하지만 라이브 set만.

그 외에도 프로그램에서 루트가 아닌 계정을 실행해야하지만 다른 사용자 환경 내에 일부 변수가 필요한 경우 변수를 전달하는 것도 유용합니다. 다음은 전자 메일 헤더를 형식화하기 위해 nullmailer vars를 전달하는 예입니다.

su -s /bin/bash -c "set -a; \
                    . /path/to/nullmailer-vars; \
                    set +a; \
                    /usr/sbin/logcheck" logcheck

2

제공된 솔루션의 대부분을 시도했지만 처음에는 아무것도 작동하지 않았습니다. 그러나 작동하지 않는 솔루션이 아니라는 것이 밝혀졌습니다. 분명히 내 ~/.bashrc파일은 다음 코드 블록으로 시작합니다.

case $- in
    *i*) ;;
    *) return;;
esac

이것은 기본적으로 case statement현재 셸의 현재 옵션 세트를 확인하여 셸이 대화식으로 실행되고 있는지 확인합니다. 쉘이 대화식으로 실행되면, 소싱으로 이동합니다.~/.bashrc 파일 합니다. 그러나에 의해 호출 된 쉘 cron에서 $-변수에는 i상호 작용 성을 나타내는 값이 포함되지 않습니다 . 따라서 ~/.bashrc파일이 완전히 소스되지 않습니다. 결과적으로 환경 변수가 설정되지 않았습니다. 이것이 문제인 경우 다음과 같이 코드 블록을 주석 처리하고 다시 시도하십시오.

# case $- in
#     *i*) ;;
#     *) return;;
# esac

이것이 유용한 것으로 나타났습니다


0

다음 env과 같이 환경 변수를 주입하도록 명령을 추가 할 수도 있습니다 .

0 * * * *   env VARIABLE=VALUE /usr/bin/mycommand
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.