추가 도구가 필요없는 솔루션이 선호됩니다.
답변
nsg의 답변과 거의 비슷합니다 : lock directory 사용하십시오 . 디렉토리 생성은 리눅스와 유닉스, * BSD와 다른 많은 OS에서 원자 적입니다.
if mkdir $LOCKDIR
then
# Do important, exclusive stuff
if rmdir $LOCKDIR
then
echo "Victory is mine"
else
echo "Could not remove lock dir" >&2
fi
else
# Handle error condition
...
fi
디버깅 목적으로 잠금 sh의 PID를 잠금 디렉토리의 파일에 넣을 수 있지만 잠금 프로세스가 여전히 실행 중인지 확인하기 위해 PID를 확인할 수 있다는 생각의 함정에 빠지지 마십시오. 많은 경쟁 조건이 그 길에 놓여 있습니다.
답변
에 추가하려면 브루스 Ediger의 대답 에 의해 영감 이 대답 , 당신은 또한 스크립트 종료에 대한 보호에 정리에 더 많은 영리를 추가해야합니다 :
#Remove the lock directory
function cleanup {
if rmdir $LOCKDIR; then
echo "Finished"
else
echo "Failed to remove lock directory '$LOCKDIR'"
exit 1
fi
}
if mkdir $LOCKDIR; then
#Ensure that if we "grabbed a lock", we release it
#Works for SIGTERM and SIGINT(Ctrl-C)
trap "cleanup" EXIT
echo "Acquired lock, running"
# Processing starts here
else
echo "Could not create lock directory '$LOCKDIR'"
exit 1
fi
답변
너무 간단 할 수 있습니다. 틀린 경우 수정 해주세요. 간단 ps
하지 않습니까?
#!/bin/bash
me="$(basename "$0")";
running=$(ps h -C "$me" | grep -wv $$ | wc -l);
[[ $running > 1 ]] && exit;
# do stuff below this comment
답변
Marco가 언급했듯이 잠금 파일을 사용합니다.
#!/bin/bash
# Exit if /tmp/lock.file exists
[ -f /tmp/lock.file ] && exit
# Create lock file, sleep 1 sec and verify lock
echo $$ > /tmp/lock.file
sleep 1
[ "x$(cat /tmp/lock.file)" == "x"$$ ] || exit
# Do stuff
sleep 60
# Remove lock file
rm /tmp/lock.file
답변
하나의 스크립트 인스턴스 만 실행되도록하려면 다음을 살펴보십시오.
그렇지 않으면 추가 도구를 호출하지 않기 때문에 check ps
또는 invoke 할 수 lsof <full-path-of-your-script>
있습니다.
보충 :
실제로 나는 다음과 같이 생각했습니다.
for LINE in `lsof -c <your_script> -F p`; do
if [ $$ -gt ${LINE#?} ] ; then
echo "'$0' is already running" 1>&2
exit 1;
fi
done
이렇게하면 동시에 pid
여러 인스턴스를 포크하고 실행하더라도 가장 낮은 프로세스 만 계속 실행됩니다 <your_script>
.
답변
bash 스크립트의 단일 인스턴스가 실행되도록하는 다른 방법 :
#!/bin/bash
# Check if another instance of script is running
pidof -o %PPID -x $0 >/dev/null && echo "ERROR: Script $0 already running" && exit 1
...
pidof -o %PPID -x $0
기존 스크립트가 이미 실행중인 경우 PID를 가져 오거나 다른 스크립트가 실행되지 않으면 오류 코드 1로 종료합니다.
답변
추가 도구가없는 솔루션을 요청했지만 다음을 사용하는 가장 좋아하는 방법입니다 flock
.
#!/bin/sh
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
echo "servus!"
sleep 10
이는의 예제 섹션에서 제공되며 man flock
추가 설명은 다음과 같습니다.
이것은 쉘 스크립트에 유용한 상용구 코드입니다. 잠 그려는 쉘 스크립트의 맨 위에 놓으면 첫 번째 실행에서 자동으로 잠 깁니다. env var $ FLOCKER가 실행중인 쉘 스크립트로 설정되지 않은 경우, 올바른 인수로 다시 실행하기 전에 flock을 실행하고 독점적 인 비 차단 잠금 (스크립트 자체를 잠금 파일로 사용)을 가져옵니다. 또한 FLOCKER env var를 올바른 값으로 설정하여 다시 실행되지 않습니다.
고려해야 할 사항 :
- 필요
flock
, 예제 스크립트를 찾을 수 없으면 오류와 함께 종료됩니다 - 추가 잠금 파일이 필요하지 않습니다
- 스크립트가 NFS에있는 경우 작동하지 않을 수 있습니다 ( https://serverfault.com/questions/66919/file-locks-on-an-nfs 참조 )
https://stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-running-at 도 참조하십시오 .