매주 크론 작업 테스트 [닫기]


237

나는이 #!/bin/bashcron.week 디렉토리에 파일을.

작동하는지 테스트하는 방법이 있습니까? 일주일을 기다릴 수 없습니다

나는 루트로 데비안 6에 있습니다


4
명령 행에서 스크립트를 실행하여 테스트 할 수 없습니까?
프레데릭 하 미디

5
crontab몇 분마다 파일을 실행 하는 별도의 항목을 추가 하고 예상 결과가 있는지 확인한 다음 crontab에서 테스트 항목을 삭제하십시오. 시도crontab -e
davin

61
아니요, 명령 줄에서 실행하는 것은 좋은 방법이 아닙니다. 명령 행에서 스크립트를 실행한다고해서 cron에서 실행할 때와 동일한 사용자가 실행되었다고 보장 할 수는 없습니다. 동일한 사용자로 실행 되더라도 다른 모든 것이 동일한 지 확신 할 수 없습니다. cron에서 실행할 때 명령 줄에서 작동하는 스크립트는 모든 종류의 이유로 실패 할 수 있습니다 .
andynormancx

8
"모든 정렬"은 약간 과장된 것일 수 있습니다 ... 사용 권한 및 환경 변수는 봄을 염두에 두는 것입니다. 별칭과 같은 다른 초기 조건을 쉽게 가질 수 있습니다.
andynormancx

3
방금 새 cron 작업을 테스트 한 결과 "모든 종류"에 다른 항목을 추가하겠습니다. bash_profile에있는 것들이 있으면 cron 작업에서 한 번 실행되지 않지만 명령 줄에서 작업을 테스트하면 완벽하게 작동합니다. 표준 명령 행에서 크론 작업을 테스트하는 것은 좋은 테스트가 아닙니다.
andynormancx

답변:


233

cron 이하는 일을 수행하고 다음을 실행하십시오 root.

run-parts -v /etc/cron.weekly

... 또는 "디렉토리가 아님 : -v"오류가 표시되면 다음 파일을 찾으십시오.

run-parts /etc/cron.weekly -v

옵션 -v은 스크립트 이름이 실행되기 전에 인쇄합니다.


4
-v 옵션을 사용하여 "디렉토리가 아님 : -v"오류를 표시하면 시스템에이 명령에 대한 매뉴얼 페이지가 없습니다. -v는 자세한 정보를 의미합니까? 나는에 CentOS 6.4 사용하고 있습니다
최대

3
"디렉토리 아님"오류를 피하려면 대신 다음을 수행해야합니다. run-parts /etc/cron.weekly -v
Craig Hyatt

22
그러나 이것은 crontab에서 설정 될 수있는 환경 변수를 고려하지 않습니다
fcurella

34
run-parts주어진 디렉토리의 스크립트를 실행합니다. cron과 관련이 없습니다.
Nicolas

23
이것은 실제로 스크립트를 실행하는 것 외에는 크론에서 실행될 때 스크립트가 실제로 작동하는지 여부를 알려주지 않습니다. 이 질문에 대한 다른 답변 중 하나에서 우수한 crontest 스크립트를 사용하십시오.
andynormancx

87

귀하의 질문의 범위를 벗어난 작은 소리 ...하지만 내가하는 일이 있습니다.

"크론 작업을 어떻게 테스트합니까?" 질문은 "다른 프로그램에서 시작한 비대화 형 컨텍스트에서 실행되는 스크립트를 어떻게 테스트합니까?"와 밀접한 관련이 있습니다. cron에서 트리거는 시간 조건이지만 많은 다른 * nix 시설은 대화식이 아닌 방식으로 스크립트 또는 스크립트 조각을 시작하며 종종 해당 스크립트가 실행되는 조건에 예기치 않은 무언가가 포함되어 버그가 정리 될 때까지 중단됩니다. ( https://stackoverflow.com/a/17805088/237059 참조 )

이 문제에 대한 일반적인 접근 방식이 도움이됩니다.

내가 좋아하는 기술 중 하나는 내가 작성한 ' crontest ' 라는 스크립트를 사용하는 것 입니다. cron 내에서 GNU 화면 세션 내에서 target 명령을 실행하여 별도의 터미널에 연결하여 진행 상황을 확인하고 스크립트와 상호 작용하며 디버거를 사용할 수도 있습니다.

이를 설정하려면 crontab 항목에 "all stars"를 사용하고 명령 행에서 첫 번째 명령으로 crontest를 지정하십시오.

* * * * * crontest /command/to/be/tested --param1 --param2

이제 cron은 1 분마다 명령을 실행하지만 crontest는 한 번에 하나의 인스턴스 만 실행되도록합니다. 명령을 실행하는 데 시간이 걸리면 "screen -x"를 수행하여 명령을 연결하고 실행할 수 있습니다. 명령이 스크립트 인 경우 상단에 "읽기"명령을 넣어 중지하고 화면 첨부가 완료 될 때까지 기다릴 수 있습니다 (첨부 후 Enter 키를 누르십시오)

명령이 bash 스크립트 인 경우 대신 다음을 수행 할 수 있습니다.

* * * * * crontest --bashdb /command/to/be/tested --param1 --param2

이제 "screen -x"로 연결하면 대화식 bashdb 세션에 직면하게되며 코드를 단계별로 실행하고 변수를 검사 할 수 있습니다.

#!/bin/bash

# crontest
# See https://github.com/Stabledog/crontest for canonical source.

# Test wrapper for cron tasks.  The suggested use is:
#
#  1. When adding your cron job, use all 5 stars to make it run every minute
#  2. Wrap the command in crontest
#        
#
#  Example:
#
#  $ crontab -e
#     * * * * * /usr/local/bin/crontest $HOME/bin/my-new-script --myparams
#
#  Now, cron will run your job every minute, but crontest will only allow one
#  instance to run at a time.  
#
#  crontest always wraps the command in "screen -d -m" if possible, so you can
#  use "screen -x" to attach and interact with the job.   
#
#  If --bashdb is used, the command line will be passed to bashdb.  Thus you
#  can attach with "screen -x" and debug the remaining command in context.
#
#  NOTES:
#   - crontest can be used in other contexts, it doesn't have to be a cron job.
#       Any place where commands are invoked without an interactive terminal and
#       may need to be debugged.
#
#   - crontest writes its own stuff to /tmp/crontest.log
#
#   - If GNU screen isn't available, neither is --bashdb
#

crontestLog=/tmp/crontest.log
lockfile=$(if [[ -d /var/lock ]]; then echo /var/lock/crontest.lock; else echo /tmp/crontest.lock; fi )
useBashdb=false
useScreen=$( if which screen &>/dev/null; then echo true; else echo false; fi )
innerArgs="$@"
screenBin=$(which screen 2>/dev/null)

function errExit {
    echo "[-err-] $@" | tee -a $crontestLog >&2
}

function log {
    echo "[-stat-] $@" >> $crontestLog
}

function parseArgs {
    while [[ ! -z $1 ]]; do
        case $1 in
            --bashdb)
                if ! $useScreen; then
                    errExit "--bashdb invalid in crontest because GNU screen not installed"
                fi
                if ! which bashdb &>/dev/null; then
                    errExit "--bashdb invalid in crontest: no bashdb on the PATH"
                fi

                useBashdb=true
                ;;
            --)
                shift
                innerArgs="$@"
                return 0
                ;;
            *)
                innerArgs="$@"
                return 0
                ;;
        esac
        shift
    done
}

if [[ -z  $sourceMe ]]; then
    # Lock the lockfile (no, we do not wish to follow the standard
    # advice of wrapping this in a subshell!)
    exec 9>$lockfile
    flock -n 9 || exit 1

    # Zap any old log data:
    [[ -f $crontestLog ]] && rm -f $crontestLog

    parseArgs "$@"

    log "crontest starting at $(date)"
    log "Raw command line: $@"
    log "Inner args: $@"
    log "screenBin: $screenBin"
    log "useBashdb: $( if $useBashdb; then echo YES; else echo no; fi )"
    log "useScreen: $( if $useScreen; then echo YES; else echo no; fi )"

    # Were building a command line.
    cmdline=""

    # If screen is available, put the task inside a pseudo-terminal
    # owned by screen.  That allows the developer to do a "screen -x" to
    # interact with the running command:
    if $useScreen; then
        cmdline="$screenBin -D -m "
    fi

    # If bashdb is installed and --bashdb is specified on the command line,
    # pass the command to bashdb.  This allows the developer to do a "screen -x" to
    # interactively debug a bash shell script:
    if $useBashdb; then
        cmdline="$cmdline $(which bashdb) "
    fi

    # Finally, append the target command and params:
    cmdline="$cmdline $innerArgs"

    log "cmdline: $cmdline"


    # And run the whole schlock:
    $cmdline 

    res=$?

    log "Command result: $res"


    echo "[-result-] $(if [[ $res -eq 0 ]]; then echo ok; else echo fail; fi)" >> $crontestLog

    # Release the lock:
    9<&-
fi

2
굉장하고 완벽한 솔루션입니다. 내가 시도한 다른 모든 기술은 실제로 작동하지 않았으므로 crontest는 문제를 쉽게 해결했습니다.
andynormancx

1
이것은 내가 필요한 것 이상 이었지만 어쨌든 훌륭한 솔루션을 위해 +1이었습니다. cron을 더 자주 실행하고 / tmp에 출력을 덤프하면 내 문제를 발견하기에 충분했습니다.
jcollum

2
멋있는. 네, 손 삽이 필요하다면 불도저를 발사 할 이유가 없습니다. :)
Stabledog

2
좋은 물건. Mac에서 참고해야 할 brew tap discoteq/discoteq; brew install flock스크립트를 수정해야합니다/usr/local/bin/flock
Claudiu

1
좋은 유틸리티! 비대화 형 컨텍스트에서 인증 문제를 진단하는 데 매우 유용합니다.
에릭 블룸

44

즉시 호환되지 않는 cron의 일부 내용을 엉망으로 만든 후에 다음 접근법이 디버깅에 유용하다는 것을 알았습니다.

crontab -e

* * * * * /path/to/prog var1 var2 &>>/tmp/cron_debug_log.log

이 작업은 1 분에 한 번 작업을 실행하며 /tmp/cron_debug_log.log파일을 살펴보면 진행중인 작업을 파악할 수 있습니다 .

그것은 당신이 찾고있는 "화재 작업"이 아니지만 처음에는 cron에서 작동하지 않은 스크립트를 디버깅 할 때 많은 도움이되었습니다.


9
이 방법을 권장합니다. 대부분의 경우 문제는 오류가 표시되지 않는다는 것입니다.
Yauhen Yakimovich

8
잘못된 줄, 어떤 배포본도 cron 쉘에 bash를 사용하지 않으므로 & >>가 작동하지 않습니다. 나는 >>/tmp/cron_debug_log.log 2>&1대신 사용 하는 것이 좋습니다
drizzt

1
무슨 /path/to/prog소란 이니?
Nathan

3
cron으로 실행할 프로그램. 이것은 usr/home/myFancyScript.sh간단 ls하거나 또는 정기적으로 실행하려는 모든 것이 될 수 있습니다 .
Automatico

이것은 나를 위해 일했습니다. 모든 것이
정상

25

잠금 파일을 사용하고 매분마다 cron 작업이 실행되도록 설정했습니다. (crontab -e 및 * * * * * / path / to / job 사용) 이렇게하면 파일을 계속 편집 할 수 있으며 매분 테스트됩니다. 또한 잠금 파일을 터치하여 cronjob을 중지 할 수 있습니다.

    #!/bin/sh
    if [ -e /tmp/cronlock ]
    then
        echo "cronjob locked"
        exit 1
    fi

    touch /tmp/cronlock
    <...do your regular cron here ....>
    rm -f /tmp/cronlock

4
flock(1)쉘에서 사용할 수도 있습니다 . 참조하십시오 man 1 flock. 자동 차단 기능을 제공하므로 이러한 용도에 매우 편리합니다.
Craig Ringer

5

무엇으로 퍼팅에 대해 cron.hourly그것을 제거 후, 시간당 cron 작업의 다음 실행 때까지 기다리고? 그것은 한 시간 안에 한 번, cron 환경에서 실행됩니다. 을 실행할 수도 ./your_script있지만 cron에서와 동일한 환경이 아닙니다.


이것은 @ Cort3z의 답변과 거의 동일하지만 덜 자세합니다.
jcollum

5

이 답변 중 어느 것도 내 특정 상황에 맞지 않습니다. 즉, 하나의 특정 크론 작업을 한 번만 실행하고 즉시 실행하고 싶었습니다.

나는 우분투 서버에 있고 cPanel을 사용하여 cron 작업을 설정합니다.

현재 설정을 적어 둔 다음 지금부터 1 분이되도록 편집했습니다. 다른 버그를 수정했을 때, 지금부터 1 분 정도 다시 편집했습니다. 그리고 모든 작업이 끝나면 설정을 이전 상태로 다시 설정하기 만하면됩니다.

예 : 지금 오후 4시 34 분이므로 16시 35 분에 35 35 * * *를 실행합니다.

그것은 매력처럼 작동했으며, 내가 기다려야했던 가장 1 분도 채 걸리지 않았습니다.

매주 크론을 모두 실행하고 싶지 않고 매 분마다 작업을 실행하고 싶지 않기 때문에 이것이 다른 대답보다 더 나은 옵션이라고 생각했습니다. 다시 테스트 할 준비가되기 전에 문제가 무엇이든 해결하는 데 몇 분이 걸립니다. 잘하면 이것은 누군가를 돕는다.


왜 cron을 사용하여 "한 번만 실행하고 즉시 실행"하시겠습니까? 스크립트를 직접 실행하는 것이 더 나을 것 같습니다.
이안 헌터

4

그 외에도 다음을 사용할 수 있습니다.

http://pypi.python.org/pypi/cronwrap

성공 또는 실패시 이메일을 보내도록 cron을 마무리합니다.


10
Cron이 이미 실행시 스크립트에서 이메일로 보내거나 출력하지 않습니까?
Erik

Cron은 사용자에게 이메일을 발송하며 일반적으로 대부분의 Cron 작업 사용자는 루트 또는 비 대화식 서비스 전용 사용자이므로 이메일을 볼 수 없습니다. 이렇게하면 오류로 인해 대량의 전자 메일이 트리거되고 서버가 루트로 바운스 될 때 서버가 채워지는 방식입니다.
dragon788

3

내가 사용하는 솔루션은 다음과 같습니다.

  1. crontab (명령 : crontab -e 사용)을 편집하여 필요한만큼 자주 (1 분 또는 5 분마다) 작업을 실행하십시오.
  2. 출력을 일부 파일로 인쇄하기 위해 cron을 사용하여 실행되어야하는 쉘 스크립트를 수정하십시오 (예 : echo "Working fine">>
    output.txt)
  3. tail -f output.txt 명령을 사용하여 output.txt 파일을 확인하십시오.이 명령은이 파일에 최근 추가 된 내용을 인쇄하므로 스크립트 실행을 추적 할 수 있습니다

2

나는 일반적으로 다음과 같이 만든 작업을 실행하여 테스트합니다.

이를 위해 두 개의 터미널을 사용하는 것이 더 쉽습니다.

작업 실행 :

#./jobname.sh

이동:

#/var/log and run 

다음을 실행하십시오.

#tailf /var/log/cron

이를 통해 크론 로그가 실시간으로 업데이트되는 것을 볼 수 있습니다. 로그를 실행 한 후 검토 할 수도 있습니다. 실시간으로 보는 것이 좋습니다.

다음은 간단한 크론 작업의 예입니다. yum 업데이트 실행 중 ...

#!/bin/bash
YUM=/usr/bin/yum
$YUM -y -R 120 -d 0 -e 0 update yum
$YUM -y -R 10 -e 0 -d 0 update

고장은 다음과 같습니다.

첫 번째 명령은 yum 자체를 업데이트하고 다음 명령은 시스템 업데이트를 적용합니다.

-R 120 : yum이 명령을 수행하기 전에 대기 할 최대 시간을 설정합니다

-e 0 : 오류 수준을 0 (범위 0-10)으로 설정합니다. 0은 반드시 알려야 할 중대한 오류 만 인쇄 함을 의미합니다.

-d 0 : 디버깅 수준을 0으로 설정합니다. 인쇄되는 양을 늘리거나 줄입니다. (범위 : 0-10).

-y : 예라고 가정하십시오. 질문에 대한 답변이 예라고 가정

cron 작업을 빌드 한 후 아래 명령을 실행하여 작업을 실행 가능하게 만들었습니다.

#chmod +x /etc/cron.daily/jobname.sh 

이것이 도움이 되었기를 바랍니다, Dorlack


2
sudo run-parts --test /var/spool/cron/crontabs/

해당 crontabs/디렉토리의 파일은 소유자실행할 수 있어야합니다. -octal700

출처 : man cronNNRooth


5
두 가지 색조. 첫째 : sudo를 실행하려면 다른 환경 (정의 된 변수)을 사용하십시오. 따라서 crontab의 버그는 'sudo'로 실행될 때 작동하지만 'root'로 실행되면 작동하지 않으며 그 반대도 마찬가지입니다. 둘째 : 'man cron'은이 정보를 보여주지 않습니다 (오케이, 제 남자는 데비안 특정 것 같습니다) ... 그들. 따라서 스크립트는 테스트되지 않았습니다. 사소한 것 : '소유자에 의해 실행 가능': 내가 아는 한, cronjobs는 루트로만 실행됩니다.
Alex

-1

나는 Webmin을 사용 하고 있습니다. 명령 행 관리가 약간 까다 롭고 뚫을 수없는 사람을위한 생산성 보석이기 때문입니다.

"시스템> 예약 된 Cron 작업> Cron 작업 편집"웹 인터페이스에 "지금 저장 및 실행"단추가 있습니다.

명령의 출력을 표시하며 정확히 필요한 것입니다.

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