Instância única de script, mas apenas com os mesmos argumentos

Instância única de script, mas apenas com os mesmos argumentos

Eu tenho este pequeno código lindo aqui que sairá de um script se houver outra instância dele em execução:

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

Mas o que estou procurando é uma função que só sairá se o script tiver sidochamado com os mesmos argumentos.

Eu sei que poderia hackear uma cat | grep | awk | cut | sed | tac | sort | uniqsolução, mas me pergunto se existe uma maneira simples de fazer isso com utilitários como pidof, psetc.

Como você faria isso?

Responder1

Você pode fazer algo assim:

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

Responder2

Eu descobri isso depois de estudar man pse adicionar alguns códigos de @goldilocks. Ele faz um bom trabalho ao lidar com argumentos com espaços e também funciona se o script for chamado como bash scriptname:

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

Responder3

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

Isso ocorrerá exit 0se dois ou mais $0processos estiverem em execução e foram invocados com os mesmos argumentos.

Responder4

Usando/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
}

Ele faz uma comparação exata entre linhas de comando sem o caminho de inicialização (como você fez no seu script). Os /proc/*/cmdlinevalores não possuem espaço, então você pode compará-los diretamente. Se a ordem dos parâmetros mudar, ele não notará isso.

informação relacionada