スクリプトの単一インスタンスですが、同じパラメータのみを使用する

スクリプトの単一インスタンスですが、同じパラメータのみを使用する

ここに実行中のスクリプトの他のインスタンスがある場合は、スクリプトから終了する素晴らしい小さなコードがあります。

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

使用/プロセス:

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値にはスペースがないため、直接比較できます。引数の順序が変わるかどうかは不明です。

関連情報