Cron スクリプトが複数回実行される

Cron スクリプトが複数回実行される

いくつかのディレクトリを USB ディスク ドライブに同期するために使用されるスクリプトがあります。 1 日に 1 回実行するように設定されていますが、それよりも長い時間がかかることがよくあります。

スクリプトの複数のコピーが同時に実行されないように、プロセスのリストをチェックし、スクリプトが存在する場合はすぐに終了します。

#!/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}

関連情報