Einzelne Instanz des Skripts, aber nur mit denselben Argumenten

Einzelne Instanz des Skripts, aber nur mit denselben Argumenten

Ich habe hier diesen schönen kleinen Code, der ein Skript beendet, wenn eine andere Instanz davon ausgeführt wird:

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

Aber was ich suche, ist eine Funktion, die nur beendet wird, wenn das Skriptmit den gleichen Argumenten aufgerufen.

Ich weiß, dass ich mir eine Lösung ausdenken könnte cat | grep | awk | cut | sed | tac | sort | uniq, aber ich frage mich, ob es dafür eine einfache Möglichkeit mit Dienstprogrammen wie pidof, psusw. gibt.

Wie würden Sie dabei vorgehen?

Antwort1

Sie können etwa Folgendes tun:

#!/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

Antwort2

Ich bin darauf gekommen, nachdem ich man psCode von @goldilocks studiert und hinzugefügt hatte. Es ist gut im Umgang mit Argumenten mit Leerzeichen und funktioniert auch, wenn das Skript folgendermaßen aufgerufen wird bash scriptname:

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

Antwort3

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

Dies ist der Fall exit 0, wenn derzeit zwei oder mehr $0Prozesse ausgeführt werden, die mit denselben Argumenten aufgerufen wurden.

Antwort4

Verwenden von/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
}

Es führt einen genauen Vergleich zwischen Befehlszeilen ohne den Startpfad durch (wie Sie es in Ihrem Skript getan haben). Die /proc/*/cmdlineWerte enthalten keine Leerzeichen, sodass Sie sie direkt vergleichen können. Wenn sich jedoch die Parameterreihenfolge ändert, wird dies nicht bemerkt.

verwandte Informationen