Como verificar / iniciar um processo | erro no script de shell

1

Se quiser verificar se um processo está sendo executado e iniciá-lo, caso contrário. Meu script abaixo é buggy e sempre diz que um processo está em execução. O que está errado?

$ ./check_n_run thisisnotrunning
./check_n_run: thisisnotrunning is already running

Aqui está o script:

$ cat check_n_run

#!/bin/sh

USAGE="usage: $0 processname"
if [ $# -ne 1 ] ; then
        echo "$USAGE" >&2
        exit 1
fi

ps ax | grep -v grep | grep $1> /dev/null
if [ $? -eq 1 ]
then
  echo "$1 not running"
  # start here      
else
  echo "$0: $1 is already running" >&2
fi

exit 0
    
por supercobra 18.07.2010 / 23:42

4 respostas

3

O problema em seu script é que (com o shell que você está usando) em um pipeline, cada comando é executado em um subshell separado e nenhum de seus status é propagado para o processo pai. Então, depois de command1 | command2 , $? é sempre 0.

Mesmo que você o tenha corrigido, seu script não é muito confiável: ele corresponderá a processos com um nome que contenha seu processo como substring. O Linux fornece o comando pidof que faz exatamente o que você está tentando fazer.

No entanto, isso ainda não é ideal, porque pode haver outro processo com o mesmo nome. Seria melhor usar um supervisor de serviço adequado, como start-stop-daemon do Debian / Ubuntu, ou um serviço iniciante. lockfile (de procmail), mencionado por Wrikken, também é uma possibilidade.

    
por 19.07.2010 / 00:27
0

Desde que o ps / grep não tenha erros, $? deveria ser 0.

edit: de acordo com Gilles (não tenho nenhum shell disponível a.t.m.):

in ksh/zsh, $? would be 1 if grep neither found a match nor errored out

Normalmente, costumo usar lockfile na inicialização desses processos ...

lockfile /path/to/lockfile && (do_something; rm -f /path/to/lockfile)

Embora seu script possa ser alterado para:

procs='ps ax | grep -v grep | grep -c $1'
if [ $procs -lt 1 ]
then
....
    
por 19.07.2010 / 00:00
0

Problema: se o seu sistema é parecido com o meu, a saída de ps ax inclui não apenas o nome do processo, mas toda a linha de comando usada para executá-lo. Então quando você corre

./check_n_run thisisnotrunning

a saída de ps ax incluirá literalmente essa linha, por isso grep sempre encontrará um resultado para thisisnotrunning . Isso explica por que seu script sempre informa que o programa está sendo executado.

Para contornar isso, existem algumas opções. Como Gilles mencionou, o melhor é usar start-stop-daemon para iniciar e parar seu script. Se isso não for uma possibilidade, você pode usar pidof para detectar se o executável fornecido está em execução. E se por algum motivo que não estavam disponíveis, você poderia usar

ps -C thisisnotrunning

que imprime apenas processos com o nome do comando fornecido.

    
por 19.07.2010 / 08:17
0

Eu acho que você tentou da maneira mais difícil. Não sei qual distribuição você usa, mas tente ver o caminho /var/run . É um diretório que inclui o pid de todo processo.

Apenas tente ls *something* . Se algo retornar, seu processo está em execução. Caso contrário, não é.

    
por 19.07.2010 / 11:41