
일부 디렉터리를 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}