스크립트의 단일 인스턴스이지만 동일한 인수만 사용 가능

스크립트의 단일 인스턴스이지만 동일한 인수만 사용 가능

여기에 다른 인스턴스가 실행 중인 경우 스크립트에서 종료되는 아름다운 작은 코드가 있습니다.

single_instance(){
    if pidof -x "${0##*/}" -o %PPID >/dev/null; then
        exit 0
    fi
}

하지만 내가 찾고 있는 것은 스크립트가 실행된 경우에만 종료되는 함수입니다.동일한 인수로 호출됨.

솔루션 을 사용하여 해킹할 수 있다는 것을 알고 있지만 , 등과 같은 cat | grep | awk | cut | sed | tac | sort | uniq유틸리티를 사용하여 이를 수행할 수 있는 간단한 방법이 있는지 궁금합니다 .pidofps

이 일을 어떻게 하시겠습니까?

답변1

다음과 같이 할 수 있습니다:

#!/bin/bash

single_instance() {

   pid=$(pidof -x "${0##*/}" -o %PPID)

   if [[ $(xargs -0 < /proc/$pid/cmdline) == $@ ]]
   then
       echo QUITTING
       exit 1
   fi
}

single_instance $(xargs -0 < /proc/$$/cmdline)

while :
do
    sleep 10
done

답변2

man ps@goldilocks에서 일부 코드를 연구하고 추가한 후에 이것을 생각해냈습니다 . 공백이 포함된 인수를 처리하는 데 효과적이며 스크립트가 다음과 같이 호출되는 경우에도 작동합니다 bash scriptname.

single_instance(){
    if ps -efww | grep "$(ps -o cmd= -p $$)$" | grep -vq " $$ "; then
        exit 0
    fi
}

답변3

fn() { IFS='
';  set -- $(ps -o args= -C "${0##*/}")
    unset IFS
    [ $(($(printf $(printf %s\\n "$@" | sort | uniq -c | sort -rn)))) -gt 1 ] &&
        exit 0
}

이는 동일한 인수로 호출된 exit 0두 개 이상의 프로세스가 현재 실행 중인 경우에 발생합니다.$0

답변4

사용/proc:

single_instance(){

   local tl=$(cat /proc/$$/cmdline)
   local l

   tl=${tl##*/}

   for pid in $(pidof -x "${0##*/}" -o %%PPID); do
        l=$(cat /proc/$pid/cmdline)
        if [ ${l##*/} = $tl ]; then
            echo "already running..."
            exit 0
        fi
    done
}

스크립트에서 했던 것처럼 실행 경로 없이 명령줄을 정확하게 비교합니다. 값 /proc/*/cmdline에는 공백이 없으므로 직접 비교할 수 있습니다. 하지만 매개변수 순서가 변경되면 이를 눈치채지 못합니다.

관련 정보