Como determinar se um processo está sendo executado ou não e utilizá-lo para criar um script de shell condicional?

101

Como posso determinar se um processo está sendo executado ou não e, em seguida, fazer um script bash executar algumas coisas com base nessa condição?

Por exemplo:

  • se o processo abc estiver em execução, faça isso

  • se não estiver em execução, faça isso.

por Nirmik 29.06.2012 / 23:53

13 respostas

162

Um script bash para fazer algo assim seria parecido com isto:

#!/bin/bash

# Check if gedit is running
# -x flag only match processes whose name (or command line if -f is
# specified) exactly match the pattern. 

if pgrep -x "gedit" > /dev/null
then
    echo "Running"
else
    echo "Stopped"
fi

Este script está apenas verificando se o programa "gedit" está sendo executado.

Ou você só pode verificar se o programa não está sendo executado assim:

if ! pgrep -x "gedit" > /dev/null
then
    echo "Stopped"
fi
    
por John Vrbanac 30.06.2012 / 00:08
34

Qualquer solução que use algo como ps aux | grep abc ou pgrep abc tem falhas.

Por quê?

Como você não está verificando se um processo específico está em execução, está verificando se há algum processo em execução que corresponda a abc . Qualquer usuário pode facilmente criar e executar um executável chamado abc (ou que contém abc em algum lugar em seu nome ou argumentos), causando um falso positivo em seu teste. Existem várias opções que você pode aplicar a ps , grep e pgrep para restringir a pesquisa, mas você ainda não obterá um teste confiável.

Então, como testar de forma confiável um determinado processo em execução?

Isso depende do que você precisa para o teste.

Eu quero garantir que o serviço abc esteja em execução e, caso contrário, inicie-o

É para isso que o init e o newstart servem. Eles iniciarão o serviço e garantirão que seu pid seja armazenado em um pidfile. Tente iniciar o serviço novamente (via init ou upstart) e ele verificará o pidfile, e o iniciará se não estiver lá, ou abortará se já estiver em execução. Isso ainda não é 100% confiável, mas é o mais próximo possível.

Veja Como posso verificar se o meu servidor de jogo é ainda em execução ... para outras soluções.

abc é o meu script. Preciso ter certeza de que apenas uma instância do meu script está sendo executada.

Nesse caso, use um arquivo de bloqueio ou um lockdir. Por exemplo,

#!/usr/bin/env bash

if ! mkdir /tmp/abc.lock; then
    printf "Failed to acquire lock.\n" >&2
    exit 1
fi
trap 'rm -rf /tmp/abc.lock' EXIT  # remove the lockdir on exit

# rest of script ...

Consulte FAQ 45 da Bash para conhecer outras formas de bloqueio.

    
por geirha 30.06.2012 / 09:29
18

Isso é o que eu uso:

#!/bin/bash

#check if abc is running
if pgrep abc >/dev/null 2>&1
  then
     # abc is running
  else
     # abc is not running
fi

Em inglês simples: se 'pgrep' retornar 0, o processo está em execução, caso contrário não é.

Leitura relacionada:

Bash Scripting :: Comparações de cordas

Manuais do Ubuntu pgrep

    
por Zuul 30.06.2012 / 00:15
5

Eu geralmente tenho um pidof -x $(basename $0) em meus scripts para verificar se ele já está em execução.

    
por Rommel Cid 14.01.2014 / 10:42
2

Analisando a ideia do @ rommel-cid, você pode usar pidof com o || (||) para executar um comando se o processo não existir e & & para executar algo se o processo existir, criando assim uma condicional rápida se / então / else. Por exemplo, aqui está um com um processo em execução (meu navegador chrome, cujo nome de processo é "chrome") e um teste para um processo que não existe. Eu suprimi a saída padrão usando 1 > / dev / null para que não seja impressa:

$ (pidof chrome 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run instea\
d"
its running? ok, so am i then
$ (pidof nosuchprocess 1>/dev/null && echo "its running? ok, so am i then" ) || echo "it's not running? ok i'll run\
 instead"
it's not running? ok i'll run instead
$
    
por yuvilio 02.03.2014 / 00:08
0

Nenhuma das soluções "simples" funcionou para mim porque o binário que preciso verificar não está instalado em todo o sistema, portanto, preciso verificar com o caminho, que, por sua vez, requer o uso de ps -ef | grep approach:

app="$_sdir/Logic 1.2.18 (64-bit)/Logic"

app_pid='ps -ef | grep "$app" | awk '{print $2}''

if 'ps -p $app_pid > /dev/null'; then
    echo "An instance of logic analyzer is appear to be running."
    echo "Not starting another instance."
    exit 5
else
    nohup "$app" &> /dev/null &
fi
    
por 04.03.2019 / 21:28
0

A primeira coisa que me veio à mente para o seu problema: o ps aux | grep -i abc mostrará os detalhes do processo se ele estiver em execução. Você pode combinar o número de linhas ou tempo para o qual está sendo executado e comparar com zero ou qualquer outra manipulação. Quando você executar o comando acima, ele mostrará pelo menos uma linha de saída, ou seja, detalhes sobre o processo criado pelo comando thi grep .. Portanto, cuide disso.
Isso deve ser um simples truque. Coloque-o no script bash e veja se é útil.

    
por drake01 30.06.2012 / 00:03
0

Usando start-stop-daemon :

/sbin/start-stop-daemon --background --make-pidfile --pidfile /tmp/foo.pid -S --startas /usr/bin/program -- arg1 arg2

Funciona como usuário normal.

    
por Martin Monperrus 19.06.2015 / 19:55
0

Descobri que a resposta aceita postada por @John Vrbanac não funcionou para mim, e que a resposta postada por @geirha não responde à pergunta original.

A solução de John Vrbanac não funcionou para verificar se um processo PHP estava em execução ou não para mim, estou executando o CentOS 7.

A resposta do @ geirha só garante que uma instância ainda não esteja em execução antes de iniciar outra. Esta não era a pergunta original, a pergunta original era verificar se um processo está sendo executado ou não.

Veja o que funcionou para mim:

Digamos que meu processo tenha a string "Jane" no nome do processo. Isso vai descobrir se está funcionando ou não. Isso funciona para scripts BASH e PHP.

ps -aux | grep "[J]ane" > /dev/null 2>&1
if [[ "$?" == "0" ]]; then
    echo "It's running"
else
    echo "It's not running"
fi
    
por Wayne Workman 11.11.2016 / 20:12
0
## bash

## function to check if a process is alive and running:

_isRunning() {
    ps -o comm= -C "$1" 2>/dev/null | grep -x "$1" >/dev/null 2>&1
}

## example 1: checking if "gedit" is running

if _isRunning gedit; then
    echo "gedit is running"
else
    echo "gedit is not running"
fi

## example 2: start lxpanel if it is not there

if ! _isRunning lxpanel; then
    lxpanel &
fi

## or

_isRunning lxpanel || (lxpanel &)

Nota : pgrep -x lxpanel ou pidof lxpanel ainda informa que lxpanel está em execução mesmo quando está extinto (zumbi); Portanto, para obter o processo de funcionamento e funcionamento, precisamos usar ps e grep

    
por Bach Lien 23.12.2017 / 19:01
-1

A partir de 23 de setembro de 2016, o pgrep parece exigir uma opção "-x" para que o script do muru funcione.

#!/bin/bash

if pgrep -x "conky" > /dev/null 2>&1
then
  echo "conky running already"
else
  echo "now starting conky"
  conky
fi
exit 0

Eu tentei e testei o script acima em uma máquina Ubuntu 16.04.1. Aproveite!

    
por dzmanto 23.09.2016 / 20:39
-1
#!/bin/bash
while [ true ]; do     # Endless loop.
  pid='pgrep -x ${1}'  # Get a pid.
  if [ -z $pid ]; then # If there is none,
    ${1} &             # Start Param to background.
  else
    sleep 60           # Else wait.
  fi
done
    
por user7449824 28.01.2017 / 19:36
-3

isProcessRunning () {if [$ (pidof $ 1) > / dev / null]; então retval = 'true'; else retval = 'false'; fi; echo $ retval; }

isProcessRunning geany

true

    
por Dominic 19.01.2016 / 20:37

Tags