prosource

cron 작업이 아직 실행되지 않은 경우에만 실행

probook 2023. 4. 18. 23:04
반응형

cron 작업이 아직 실행되지 않은 경우에만 실행

cron 작업을 작성한 데몬에 대한 일종의 워치독으로 설정하려고 합니다.데몬이 에러 아웃 되어 실패했을 경우, cron 작업이 정기적으로 데몬을 재기동하도록 합니다.이것이 얼마나 가능한지는 잘 모르겠습니다만, 몇개의 cron 튜토리얼을 읽어보았지만, 제가 찾고 있는 것을 실행할 수 있는 것을 찾을 수 없었습니다.

데몬은 셸 스크립트에서 시작되므로 cron 작업의 이전 실행이 아직 실행되지 않은 경우에만 cron 작업을 실행할 수 있는 방법을 찾고 있습니다.

게시물을 찾았는데, 잠금 파일을 사용하여 하려는 작업에 대한 해결책을 제공했습니다. 더 나은 방법이 없을지 모르겠습니다.

사용하다flock새롭다.그게 더 낫지.

이제 코드를 직접 작성할 필요가 없습니다.자세한 이유는 이쪽에서 확인하세요.https://serverfault.com/a/82863

/usr/bin/flock -n /tmp/my.lockfile /usr/local/bin/my_script

제가 작성한 프린트 스풀러 프로그램에 대해 이렇게 합니다.그것은 셸 스크립트일 뿐입니다.

#!/bin/sh
if ps -ef | grep -v grep | grep doctype.php ; then
        exit 0
else
        /home/user/bin/doctype.php >> /home/user/bin/spooler.log &
        #mailing program
        /home/user/bin/simplemail.php "Print spooler was not running...  Restarted." 
        exit 0
fi

2분 간격으로 운행되며 상당히 효과적입니다.어떤 이유로 프로세스가 실행되지 않을 경우 특별한 정보를 이메일로 보내드립니다.

다른 사람들이 말했듯이, PID 파일을 쓰고 확인하는 것이 좋은 해결책입니다.bash의 실장은 다음과 같습니다.

#!/bin/bash

mkdir -p "$HOME/tmp"
PIDFILE="$HOME/tmp/myprogram.pid"

if [ -e "${PIDFILE}" ] && (ps -u $(whoami) -opid= |
                           grep -P "^\s*$(cat ${PIDFILE})$" &> /dev/null); then
  echo "Already running."
  exit 99
fi

/path/to/myprogram > $HOME/tmp/myprogram.log &

echo $! > "${PIDFILE}"
chmod 644 "${PIDFILE}"

아무도 런원에 대해 언급하지 않았다는 것이 놀랍다.이것으로 고민을 해결했습니다.

 apt-get install run-one

그 후 추가run-onecrontab 스크립트 전에

*/20 * * * * * run-one python /script/to/run/awesome.py

이 askubuntu SE의 답변을 확인하십시오.자세한 정보에 대한 링크도 거기서 찾을 수 있습니다.

cron을 통해 시도하지 마십시오.무슨 일이 있어도 cron에게 스크립트를 실행시키고, 그 후 스크립트에 의해 프로그램이 실행 중인지 판단하고, 필요에 따라서 기동하도록 지시합니다(Ruby 또는 Python 또는 마음에 드는 스크립트 언어를 사용할 수 있습니다).

crontab에서 직접 원라이너로 할 수도 있습니다.

* * * * * [ `ps -ef|grep -v grep|grep <command>` -eq 0 ] && <command>

php 스크립트를 실행할 때 사용하는 방법은 다음과 같습니다.

crontab:

* * * * * php /path/to/php/script.php &

php 코드:

<?php
if (shell_exec('ps aux | grep ' . __FILE__ . ' | wc  -l') > 1) {
    exit('already running...');
}
// do stuff

이 명령어는 시스템프로세스 목록에서 현재 php 파일명을 검색하고 있습니다.행 카운터(wc - l)가 존재하는 경우 검색 명령어 자체에 파일명이 포함되어 있기 때문에 1보다 커집니다.

따라서 php crons를 실행하고 있는 경우 위의 코드를 php 코드의 선두에 추가하면 1회만 실행됩니다.

Earlz에 대한 후속 응답으로 $PID.running 파일을 시작할 때 생성하고 종료할 때 삭제하는 래퍼 스크립트가 필요합니다.래퍼 스크립트는 실행할 스크립트를 호출합니다.대상 스크립트가 실패하거나 오류가 발생하여 pid 파일이 삭제될 경우 래퍼가 필요합니다.

★★★★★★★★★★★★★★★★ lockruncron 작업에 래퍼 스크립트를 작성할 필요가 없습니다.http://www.unixwiz.net/tools/lockrun.html

# one instance only (works unless your cmd has 'grep' in it)
ALREADY_RUNNING_EXIT_STATUS=0
bn=`basename $0`
proc=`ps -ef | grep -v grep | grep "$bn" | grep -v " $$ "`
[ $? -eq 0 ] && {
    pid=`echo $proc | awk '{print $2}'`
    echo "$bn already running with pid $pid"
    exit $ALREADY_RUNNING_EXIT_STATUS
}

업데이트.. 무리를 사용하는 더 나은 방법:

/usr/bin/flock -n /tmp/your-app.lock /path/your-app args 

monit 등의 기존 툴을 사용하는 것이 좋습니다.이 툴은 프로세스를 감시하고 자동으로 재시작합니다.자세한 내용은 이쪽에서 확인하실 수 있습니다.대부분의 배포에서 쉽게 사용할 수 있습니다.

이건 날 실망시킨 적이 없어

one.sh:

LFILE=/tmp/one-`echo "$@" | md5sum | cut -d\  -f1`.pid
if [ -e ${LFILE} ] && kill -0 `cat ${LFILE}`; then
   exit
fi

trap "rm -f ${LFILE}; exit" INT TERM EXIT
echo $$ > ${LFILE}

$@

rm -f ${LFILE}

cron 작업:

* * * * * /path/to/one.sh <command>

문서: https://www.timkay.com/solo/

solo는 프로그램이 한 번에 두 개 이상의 복사본을 실행할 수 없도록 하는 매우 단순한 스크립트(10줄)입니다.이전 작업이 완료되기 전에 작업이 실행되지 않도록 하려면 cron을 사용하면 유용합니다.

* * * * * solo -port=3801 ./job.pl blah blah

Ransanden의 답변을 개선하기 위해 다음과 같이 제안하고 싶습니다(댓글을 투고합니다만, 평판이 좋지 않습니다).):

#!/usr/bin/env bash

PIDFILE="$HOME/tmp/myprogram.pid"

if [ -e "${PIDFILE}" ] && (ps -p $(cat ${PIDFILE}) > /dev/null); then
  echo "Already running."
  exit 99
fi

/path/to/myprogram

이것에 의해, 잘못된 일치(및 그리핑의 오버헤드)가 발생할 가능성이 회피되어 출력이 억제되어 ps의 종료 상태에만 의존합니다.

간단한 커스텀 php로 충분합니다.셸 스크립트와 혼동할 필요가 없습니다.

php /home/mypath/mypath를 실행한다고 가정합니다.php(실행하지 않는 경우)

다음 커스텀 php 스크립트를 사용하여 동일한 작업을 수행합니다.

다음 /home/mypath/mypath를 만듭니다.php

<?php
    $cmd = $argv[1];
    $grep = "ps -ef | grep '".$cmd."'";
    exec($grep,$out);
    if(count($out)<5){
        $cmd .= ' > /dev/null 2>/dev/null &';
        exec($cmd,$out);
        print_r($out);
    }
?>

그런 다음 cron에 다음을 추가합니다.

* * * * * php /home/mypath/forever.php 'php /home/mypath/example.php'

그 루트를 사용하는 경우는, grep 경유로 ps가 아닌 pgrep(사용 가능한 경우)를 사용하는 것을 검토해 주세요.하지만, 개인적으로, 저는 그 형식의 대본에서 많은 마일리지를 얻었어요.

while(1){
  call script_that_must_run
  sleep 5
}

이는 실패할 수 있지만 cron 작업이 필수 작업에 가장 적합한 방법인 경우가 많습니다.그냥 다른 대안일 뿐이야.

언급URL : https://stackoverflow.com/questions/2366693/run-cron-job-only-if-it-isnt-already-running

반응형