Один экземпляр скрипта, но только с теми же аргументами

Один экземпляр скрипта, но только с теми же аргументами

У меня есть вот этот прекрасный маленький код, который завершит работу скрипта, если запущен другой его экземпляр:

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

Но я ищу функцию, которая выйдет только в том случае, если скрипт был завершен.вызван с теми же аргументами.

Я знаю, что я мог бы придумать решение cat | grep | awk | cut | sed | tac | sort | uniq, но мне интересно, есть ли простой способ сделать это с помощью таких утилит, как pidof, psи т. д.

Как бы вы это сделали?

решение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не содержат пробелов, поэтому вы можете сравнивать их напрямую. Однако если порядок параметров изменится, он этого не заметит.

Связанный контент