여러 번 실행되는 Cron 스크립트

여러 번 실행되는 Cron 스크립트

일부 디렉터리를 USB 디스크 드라이브에 동기화하는 데 사용되는 스크립트가 있습니다. 하루에 한 번 실행되도록 설정되어 있지만 그보다 오래 걸리는 경우가 많습니다.

스크립트의 여러 복사본이 동시에 실행되지 않도록 하기 위해 프로세스 목록을 확인하고 스크립트가 있으면 즉시 종료합니다.

#!/bin/bash

#check if we are already running
running=$(ps aux | /usr/bin/grep -i "usb_sync" | /usr/bin/grep -v grep | /usr/bin/grep -c bash)
echo "usb_sync $running" >/opt/local/backup/usb_sync_log
#If we are, the quit
if [ $running -gt 1 ] ; then
  exit 0
fi

문제는 이 검사가 sudo 및 CLI를 통한 수동 호출을 통해 실행할 때 제대로 작동한다는 것입니다. 그러나 cron을 통해 실행되면 관계없이 시작됩니다. 몇 가지 다른 변형을 시도했지만 모두 실행되는 것 같습니다.

이것은 FreeNAS 11.2에 있습니다.

답변1

파일 pid은 스크립트의 다중 실행을 방지하는 일반적인 접근 방식입니다. 다음과 같이 사용할 수 있습니다.

#!/bin/bash

PIDFILE=/home/vagrant/forever.pid
if [ -f $PIDFILE ]
then
  PID=$(cat $PIDFILE)
  ps -p $PID > /dev/null 2>&1
  if [ $? -eq 0 ]
  then
    echo "Process already running"
    exit 1
  else
    ## Process not found assume not running
    echo $$ > $PIDFILE
    if [ $? -ne 0 ]
    then
      echo "Could not create PID file"
      exit 1
    fi
  fi
else
  echo $$ > $PIDFILE
  if [ $? -ne 0 ]
  then
    echo "Could not create PID file"
    exit 1
  fi
fi

sleep 25d
rm $PIDFILE

sleep 25d실행할 실제 명령은 어디에 있습니까? 나는 이것을 읽는 것이 좋습니다블로그 게시물이 문제를 처리하는 다양한 방법에 대한 자세한 설명을 보려면 위의 스크립트는 거기에서 가져온 것입니다.

cron 파일에 설정된 스크립트를 실행하기 위한 사용자의 접근 권한을 확인해야 합니다. 현재 스크립트는 액세스 권한이 충분하지 않기 때문에 스크립트가 이미 실행 중인지 식별하지 못할 수도 있습니다. 어떤 방식으로든 pid 파일을 사용하는 것이 이 문제를 처리하는 데 더 좋고 오류가 덜 발생하는 솔루션처럼 보입니다.

답변2

훨씬 쉽게 할 수 있습니다. 플래그 파일을 만듭니다. 스크립트 시작 부분에 다음을 사용할 수 있습니다.

    ## Basic config
SCRIPTNAME=$(basename "$0")
RUNFILE="${SCRIPTNAME}.run"
# 25h in seconds adjust to your needs.
MAX_AGE=90000


    # check for running process
    if [ -f "$RUNFILE" ]; then
      echo "process still running - exit"
      if [ $(( $(date +%s) - $(date +%s --reference $RUNFILE) )) -gt ${MAX_AGE} ]; then
         rm $RUNFILE;
      else 
         exit
      fi
    fi
    touch $RUNFILE

<your code>

rm ${RUNFILE}

실행 파일의 내용은 실행 중인 프로세스의 PID일 수 있습니다. 실행 중인 프로세스가 있으면 분석하기가 더 쉬울 것입니다.

대신에

touch ${RUNFILE}

사용

echo $$ >${RUNFILE}

관련 정보