
いくつかのディレクトリを 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}