태그 보관물: lock

lock

bash 스크립트 인스턴스를 하나만 실행하는 방법은 무엇입니까? 필요없는 솔루션이

추가 도구가 필요없는 솔루션이 선호됩니다.



답변

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를 올바른 값으로 설정하여 다시 실행되지 않습니다.

고려해야 할 사항 :

https://stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-running-at참조하십시오 .