cron은“.bashrc”및“.bash_profile”에 정의 된 변수를 무시합니다.


49

/ etc / crontab 파일에서 "SHELL"변수를 정의했습니다.

[martin@martin ~]$ grep SHELL /etc/crontab 
SHELL=/usr/local/bin/bash
[martin@martin ~]$ file /usr/local/bin/bash
/usr/local/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 8.0 (800107), stripped
[martin@martin ~]$ 

또한 / etc / crontab 파일의 모든 스크립트는 "martin"사용자로 시작됩니다. 그러나 /home/martin/.bash_profile (로그인 쉘의 경우) 및 /home/martin/.bashrc (비 로깅 쉘의 경우)에는 cron 작업의 경우 무시되지만 일부 시스템에 로그인 할 때 사용되는 일부 변수가 포함됩니다 SSH 또는 새 bash 세션을여십시오. 왜 cron이 그 변수를 무시합니까? cron은 단순히 "martin"사용자에 대한 권한으로 "/ usr / local / bin / bash my-script.sh"를 실행하지 않습니까?


2
우분투 사용자들은 우분투의 기본은 참고하실 수 .bashrc있습니다 실행을 중지 라인 (non-interactive) 형 모드 쉘에 있습니다.
joeytwiddle

답변:


71

작업을 실행중인 사용자의 스크립트 맨 위 또는 작업 시작 부분에서 원하는 파일을 제공 할 수 있습니다. "source"명령은 내장되어 있습니다. 변경 사항을로드하기 위해 해당 파일을 편집 한 경우에도 동일한 작업을 수행합니다.

* * * * * source /home/user/.bash_profile; <command>

또는

#!/bin/bash
source /home/user/.bash_profile

<commands>

2
cron이 bash쉘을 사용하지 않으면 "소스"가 작동하지 않을 수 있습니다 . 쉘이 인 경우를 처리 할 수있는 답변을 추가했습니다 sh.
조나단


23

대화식 쉘이 아니기 때문입니다. 일부 터미널을 열 때도 마찬가지입니다.

이 질문을 살펴보십시오 . .bashrc 파일은 무엇입니까? | 슈퍼 유저

그리고 이것에 :

.bashrc, .bash_profile 및 .environment의 차이점은 무엇입니까? | 스택 오버플로

연결이 로그인 쉘인지 아닌지, 대화식 쉘인지 아닌지에 따라 다른 스크립트가 실행됩니다.

bashrc를 만들고 싶다면 다음과 같이 변경해야합니다.

Bash가 비 대화식으로 시작될 때, 예를 들어, 쉘 스크립트를 실행하기 위해 환경에서 변수 BASH_ENV를 찾고, 거기에 표시되면 값을 확장하고, 확장 된 값을 읽고 실행할 파일 이름으로 사용합니다. . Bash는 다음 명령이 실행 된 것처럼 동작합니다.

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi 

그러나 PATH 변수의 값은 파일 이름을 검색하는 데 사용되지 않습니다.

위에서 언급 한 것처럼 비 대화식 쉘이 --login옵션으로 호출 되면 Bash는 로그인 쉘 시작 파일에서 명령을 읽고 실행하려고 시도합니다.

출처 : 배쉬 시작 파일 | 배쉬 참조 매뉴얼 | gnu.org


따라서 Cron 내부에 BASH_ENV를 설정하면 cron은 비 대화식이고 로그인하지 않기 때문에 cron bash 스크립트가이를 소싱합니다.
CMCDragonkai

12

쉘을 사용중인 source경우 실행하지 못할 수 있습니다 sh. crontab에 다음 줄을 추가하여 변경할 수 있습니다.

SHELL=/bin/bash
* * * * * source "/root/.bashrc"; <command>

환경을 지정할 수도 있습니다.

BASH_ENV="/root/.bashrc"
* * * * * <command>

또는 /home/user/.bashrc사용자 cron 작업 인 경우 로컬을 사용할 수 있습니다 (예 :) crontab -e.

있는 경우 .bash_profile바꿀 .bashrc수 있습니다.

크레딧 : cron shell을 바꾸는 방법은 무엇입니까?


이는 기본적으로 크론 작업 인 Acquia Cloud Scheduled 작업에도 효과적입니다. 다음과 같이 동일한 작업을 수행 할 수 있습니다.SHELL=/bin/bash && source /home/YOUR_USER_NAME/.bash_profile && sh ....
Alejandro Moreno

1

.bashrccronjob에서 소스를 소싱하는 데 방해가 될 수있는 다른 것은 대화식 쉘을 감지하기 위해이 파일이 수행하는 점검입니다.

예를 들어 Ubuntu 18.04에서 .bashrc사용자 의 기본값 은 다음과 같이 시작합니다.

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

소싱은 즉시 종료되므로 유용한 작업을 수행하지 않습니다.


1

다음 -l과 같은 옵션으로 bash를 호출 할 수 있습니다 .

* * * * * /bin/bash -l /path/to/script arg1 arg2

-l옵션은 bash를 로그인 쉘로 만듭니다 . 따라서 사용자의을 읽습니다 .bash_profile. 에서 .bashrc명시 적으로 소스를 제공하지 않으면 사용자를 읽지 않습니다 .bash_profile. 비 대화식 쉘은 자동으로 읽지 않기 때문 .bashrc입니다. 그러나 대화식 쉘에 유용한 것을 설정 .bashrc하기 때문에 cron 작업이 필요하지 않습니다 ..bashrc

변형 :

bash가 PATH에 있으면 절대 경로를 지정할 필요가 없습니다.

* * * * * bash -l /path/to/script arg1 arg2

최적화는 다음을 사용하여 현재 쉘을 바꾸는 것입니다 exec.

* * * * * exec bash -l /path/to/script arg1 arg2

1

bash 인지 또는 일반 프로그래밍 언어 (예 : perl또는 python) 인지에 따라 다르게 작동합니다 .

디자인으로의 설정 ~/.bash_profile, ~/.bashrc때 사용자가 물건을 설정하는 등은 bash재생 쉘의 역할 (로그인 쉘, interractive 쉘). xterm(대화식 쉘) 또는 ssh세션 (로그인 쉘) 또는 콘솔 (로그인 쉘) 에있는 환경을 생각하십시오 .

다른 한편으로, 서비스를 관리하기위한 많은 스크립트에 대해 생각 bash하는 강력한 프로그래밍 언어 이기도 systemd합니다. 다른 스타일의 작업이 필요합니다. 예를 들어, 개발자가 시스템 스크립트 또는 bash프로그램을 작성하는 경우 사용자가 ~/.bash_profile자동으로 소스를 제공하지 않습니다 . 쉘이 아닌 정상적인 프로그램입니다. 일반 프로그램 (프로그램 포함 bash)은 현재 작업 환경 (쉘)의 설정을 자연스럽게 상속 하지만 설정 하지는 않습니다 .

cronin에 대한 프로그램을 작성하면 bash–it에 기록됩니다 bash. 사실, 우리는 그것을 쓸 수 있습니다 python하거나 perl또는 다른 progamming의 language-은 우리가 소스 옵션을 가질 수 bash의을 ~/.bash_profile(읽기 : 당신의 프로그래밍 언어와 동일한 언어로 발생하는 사용자의 쉘의 설정) :

[ -f /home/user/.bash_profile ] && . /home/user/.bash_profile

그러나 특정 사용자가 bash자신의 쉘로 사용하지 않으면 어떻게됩니까? 그는 / 그녀는 사용할 수 있습니다 zsh, ksh, fish공공 사용을위한 프로그램을 작성하는 경우 등 그래서, 실제로 정말 작동하지 않을 것입니다.

따라서 ~/.bash_profile그것이 효과가 있다고 생각하면 소스를 얻을 수 있습니다 . 그러나 여기서는 파일을 소싱 할 수 있는지 여부가 아니라 시스템에서 어떻게 작동해야하는지에 관한 것 입니다 . 디자인 컨셉 입니다. 간단히 말해, 쉘과 프로그램 언어라는 두 가지 역할을하는 것으로 간주 해야 bash합니다 . 그러면 모든 것이 이해하기 훨씬 쉬워 질 것입니다.


0

NVM을 사용하는 cron에서 노드 응용 프로그램을 실행할 때 동일한 문제가 발생했습니다. cron에서 .bashrc 파일을 읽도록 bash 셸을 만들려면 대화 형 셸 옵션`-l을 사용하여 bash 명령을 호출하십시오.

예 : * * * * * /bin/bash -lc '/home/user/myapp.sh restart'

그래도 작동하지 않으면 crontab에서 경로 변수를 설정하십시오.

41 7 * * * /bin/bash -lc "PATH=$PATH:/home/user/.nvm/versions/node/v8.10.0/bin && /home/user/script.sh restart "

-1

그것을 다루는 내 방법은 다음과 같습니다.

1) 변수를 (끝 )에 넣습니다 ~/.profile.

myVarInDotProfile="someValue"

2)~/cronDaily.sh 내 명령과 반복적 인 소싱을 포함하는 (매일의) cron 작업 ( )에 대한 Bash 스크립트 만들기 ~/.profle:

source ~/.profile
command ${myVarInDotProfile}/

3) 에서 스크립트 실행을 예약 crontab하여 매일 실행하십시오.

0 0 * * * bash ~/cronDaily.sh

내 변수는 무시되지 않았고 명령이 성공적으로 실행되었습니다.


어떤 사람들은 그러한 강력한 소싱 ~/.profile이 문제가 있다고 말할 수도 있습니다 . 내 특별한 경우에는 왜 그것이 문제인지 알지 못하지만 전용 파일을 만드는 것이 좋습니다.

일반적으로 더 좋은 방법이있을 수 있지만 많은 고통을 겪은 후에 저에게 도움이되었으며 Bash 4.3.46부터는에서 파일을 소스 할 수 없다는 원칙을 설명합니다 crontab.

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