2012-02-01 4 views
4

한 번만 실행하려는 스크립트가 있습니다. 스크립트가 두 번째로 호출되면 lockfile이 있는지 확인합니다. lockfile이 존재하면 프로세스가 실제로 실행 중인지 확인하고 싶습니다.pgrep을 사용하여 프로세스가 실행 중인지 확인

나는 pgrep을 만지작 된 적이 있지만 예상 된 결과받지 오전 :

#!/bin/bash 
COUNT=$(pgrep $(basename $0) | wc -l) 
PSTREE=$(pgrep $(basename $0) ; pstree -p $$) 
echo "###" 
echo $COUNT 
echo $PSTREE 
echo "###" 
echo "$(basename $0) :" `pgrep -d, $(basename $0)` 
echo sleeping..... 
sleep 10 

내가지고있어 결과는 : 나는 '왜

$ ./test.sh 
### 
2 
2581 2587 test.sh(2581)---test.sh(2587)---pstree(2591) 
### 
test.sh : 2581 
sleeping..... 

이해가 안가 단지 하나의 프로세스가 실제로 실행 중일 때 "2"를 얻습니다.

아이디어가 있으십니까? 나는 그것이 내가 부르는 방식이라고 확신한다. 나는 여러 가지 조합을 시도해 보았고 그것을 이해하는 것처럼 보일 수 없다.

해결책 : 내가하고 결국 무엇

이 (내 스크립트의 일부를)하고 있었다 : pgrep을위한

function check_lockfile { 
    # Check for previous lockfiles 

    if [ -e $LOCKFILE ] 
    then 
     echo "Lockfile $LOCKFILE already exists. Checking to see if process is actually running...." >> $LOGFILE 2>&1 
     # is it running? 
     if [ $(ps -elf | grep $(cat $LOCKFILE) | grep $(basename $0) | wc -l) -gt 0 ] 
     then 
      abort "ERROR! - Process is already running at PID: $(cat $LOCKFILE). Exitting..." 
     else 
      echo "Process is not running. Removing $LOCKFILE" >> $LOGFILE 2>&1 
      rm -f $LOCKFILE 
     fi 
    else 
     echo "Lockfile $LOCKFILE does not exist." >> $LOGFILE 2>&1 
    fi 
} 

function create_lockfile { 
    # Check for previous lockfile 
    check_lockfile 

    #Create lockfile with the contents of the PID 
    echo "Creating lockfile with PID:" $$ >> $LOGFILE 2>&1 
    echo -n $$ > $LOCKFILE 
    echo "" >> $LOGFILE 2>&1 
} 

# Acquire lock file 
create_lockfile >> $LOGFILE 2>&1 \ 
|| echo "ERROR! - Failed to acquire lock!" 
+0

'$ ps -elf | grep processname'을 실행하십시오. –

+0

사소한 코드로,'[\'grep something | wc -l \'-gt 0]'은'grep something'으로 단순화 될 수 있습니다. http://partmaps.org/era/unix/award-example-backticks.html – tripleee

+0

고맙습니다. 그래서 당신은이에 대한 말 : 경우 [$ (추신 -elf | 그렙 $ (고양이 $의 LOCKFILE) | 그렙 $ (기본 이름 $ 0) | 화장실 -l) -gt 0]이에 대한 대체 : [경우 $ (추신 -elf | 그렙 $ (고양이 $의 LOCKFILE) | 그렙 $ (기본 이름 $ 0))] 내가 제대로 이해 했습니까? – jared

답변

3

인수는 확장 된 정규 표현식 패턴이다. 이 경우 pgrep $(basename $0) 명령은 pgrep test.sh으로 표시되며 test 다음에 문자가 있고 문자 다음에 sh이 뒤 따르는 모든 프로세스와 일치하는 것으로 평가됩니다. 따라서 일치 할 것입니다 btest8sh, atest_shell

잠금 파일을 만들어야합니다. 잠금 파일이 있으면 프로그램이 종료되어야합니다.

lock=$(basename $0).lock 
if [ -e $lock ] 
then 
    echo Process is already running with PID=`cat $lock` 
    exit 
else 
    echo $$ > $lock 
fi 
+0

감사의 Shiplu. 내 스크립트에서 lockfile을 생성하려면 다음과 같이하십시오. lockfile -r 0 -l 21600 $ LOCKFILE >> $ LOGFILE 2> & 1 \ || abort "ERROR! - 잠금을 획득하지 못했습니다! 이미 실행 중일 것입니다 ..." 이전 실행 후 삭제되지 않은 잠금 파일이있는 경우에 대비하여 추가 검사로 pgrep 부분을 추가했습니다. – jared

0

이미 잠금 파일을 여는 중입니다. 삶을 편하게 만드려면 그것을 사용하십시오.

잠금 파일에 프로세스 ID를 작성합니다. 잠금 파일이있는 것을 확인한 후 잠금 파일을 읽고 프로세스 ID가 잠금으로 설정되어 있는지 확인하고 해당 프로세스가 아직 실행 중인지 확인하십시오. 새로운 프로세스는 동일한 프로세스 ID로 시작되는

그런 다음 버전 2에, 당신은 또한 경우에 대비하는 등 프로그램 이름, 프로그램 인수, 프로그램 시작 시간을 쓸 수 있습니다.

0

스크립트의 상단에 넣어이 ...

pid=$$ 
script=$(basename $0) 
guard="/tmp/$script-$(id -nu).pid" 
if test -f $guard ; then 
    echo >&2 "ERROR: Script already runs... own PID=$pid" 
    ps auxw | grep $script | grep -v grep >&2 
    exit 1 
fi 
trap "rm -f $guard" EXIT 
echo $pid >$guard 

그리고 네, 경비에 추가하여 고정 할 수있는 테스트 및 에코 명령 사이의 경쟁 조건에 대한 작은 창, 거기에 파일을 만든 다음 첫 번째 행이 실제로 우리 자신의 PID인지 확인하십시오. 또한 생산 버전에서 if의 진단 출력을 주석 처리 할 수 ​​있습니다.

관련 문제