Comando Linux / Unix para determinar se o processo está em execução?

Preciso de um comando shell/bash independente da plataforma (Linux|Unix/OSX) que irá determinar se um processo específico está em execução. = = referências = = mysqld, httpd... Qual é a maneira mais simples/comando de fazer isso?

Author: Highway of Life, 2012-02-02

14 answers

Enquanto pidof e pgrep são grandes ferramentas para determinar o que está a correr, eles estão ambos, infelizmente, indisponíveis em alguns sistemas operacionais. Uma segurança definitiva seria usar o seguinte: ps cax | grep command

A saída no Gentoo Linux:

14484 ?        S      0:00 apache2
14667 ?        S      0:00 apache2
19620 ?        Sl     0:00 apache2
21132 ?        Ss     0:04 apache2

A saída no OS X:

42582   ??  Z      0:00.00 (smbclient)
46529   ??  Z      0:00.00 (smbclient)
46539   ??  Z      0:00.00 (smbclient)
46547   ??  Z      0:00.00 (smbclient)
46586   ??  Z      0:00.00 (smbclient)
46594   ??  Z      0:00.00 (smbclient)

Tanto no Linux quanto no OS X, o grep devolve um código de saída para que seja fácil verificar se o processo foi encontrado ou Não:

#!/bin/bash
ps cax | grep httpd > /dev/null
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

Além disso, se você quiser a lista de PIDs, você pode facilmente grep para aqueles também:

ps cax | grep httpd | grep -o '^[ ]*[0-9]*'

Cuja saída é a mesma no Linux e no OS X:

3519 3521 3523 3524

A saída do seguinte é uma string vazia, tornando esta abordagem segura para processos que não estão em execução:

echo ps cax | grep aasdfasdf | grep -o '^[ ]*[0-9]*'

Esta abordagem é adequada para escrever um simples teste de texto vazio, e depois até mesmo para iterar através do Descoberto PIDs.

#!/bin/bash
PROCESS=$1
PIDS=`ps cax | grep $PROCESS | grep -o '^[ ]*[0-9]*'`
if [ -z "$PIDS" ]; then
  echo "Process not running." 1>&2
  exit 1
else
  for PID in $PIDS; do
    echo $PID
  done
fi

Pode testá-lo gravando-o num ficheiro (chamado "running" ) com permissões de execução (chmod +x em execução) e executando-o com um parâmetro: ./running "httpd"

#!/bin/bash
ps cax | grep httpd
if [ $? -eq 0 ]; then
  echo "Process is running."
else
  echo "Process is not running."
fi

Aviso!!!

Por Favor, tenha em mente que você está simplesmente analisar a saída de ps ax, o que significa que, como visto no Linux saída, não é simplesmente de correspondência de processos, mas também os argumentos passados para o programa. Eu recomendo ser o mais específico possível ao usar este método (por exemplo, ./running "mysql" também irá corresponder aos processos "mysqld"). Recomendo vivamente o uso de which para verificar um caminho completo sempre que possível.


Referências:

Http://linux.about.com/od/commands/l/blcmdl1_ps.htm

Http://linux.about.com/od/commands/l/blcmdl1_grep.htm

 154
Author: Caleb Gray, 2012-08-08 17:32:22
Devias conhecer o PID !

Encontrar um processo tentando fazer algum tipo de reconhecimento de padrões nos argumentos do processo (como pgrep "mysqld") é uma estratégia que está condenada a falhar mais cedo ou mais tarde. E se tiveres dois mysqld a funcionar? Esquece essa abordagem. Você pode acertar temporariamente e pode funcionar por um ano ou dois, mas então algo acontece que você não pensou.

Só o ID do processo (pid) é verdadeiramente único.

Guarda sempre o pid quando lançares algo no fundo. In Bash isto pode ser feito com a variável Bash $!. Vais poupar-te tanto trabalho ao fazê-lo.

Como determinar se o processo está a correr (por pid)

Então agora a questão torna-se saber se um pid está a correr.

Simplesmente faça:

ps -o pid= -p <pid>
Isto é POSIX e, portanto, portátil. Ele irá devolver o pid em si se o processo estiver em execução ou não devolver nada se o processo não estiver em execução. Estritamente falando, o comando irá retornar um uma única coluna, o pid, mas dado que lhe demos um cabeçalho de título vazio (o material que precede imediatamente o sinal de igual) e esta é a única coluna pedida, então o comando ps não irá usar o cabeçalho de todo. Que é o que queremos, porque facilita a análise.

Isto vai funcionar no Linux, BSD, Solaris, etc.

Outra estratégia seria testar o valor de saída do comando ps acima. Deve ser zero se o processo estiver em execução e não-zero se não estiver. o POSIX spec diz que ps deve sair >0 se ocorreu um erro, mas não está claro para mim o que constitui 'um erro'. Portanto, eu não estou pessoalmente usando essa estratégia, embora eu tenho certeza que ele vai funcionar também em todas as plataformas Unix/Linux.

 22
Author: peterh, 2013-10-03 10:53:02

Na maioria das distribuições Linux, você pode usar pidof(8).

Irá imprimir os ids do processo de todas as instâncias em execução de processos especificados, ou nada se não houver instâncias em execução.

Por exemplo, no meu sistema (tenho quatro instâncias de bash e uma instância de remmina em execução):
$ pidof bash remmina
6148 6147 6144 5603 21598

Em outros Unices, pgrep ou uma combinação de ps e {[6] } irá alcançar a mesma coisa, como outros correctamente salientaram.

 13
Author: Frédéric Hamidi, 2012-02-02 18:14:22

A forma mais simples é usar ps e grep:

command="httpd"
running=`ps ax | grep -v grep | grep $command | wc -l`
if [ running -gt 0 ]; then
    echo "Command is running"
else
    echo "Command is not running"
fi

Se o seu comando tiver alguns argumentos de comando, então Poderá também colocar mais 'grep cmd_arg1' após 'grep $command' para filtrar outros processos possíveis em que não esteja interessado.

Exemplo: mostra-me se algum processo java com argumento fornecido:

- Djava.util.log.configuracao.ficheiro=registo.propriedades

Está a correr

ps ax | grep -v grep | grep java | grep java.util.logging.config.file=logging.properties | wc -l
 6
Author: Pawel Solarski, 2012-10-26 08:20:24

Isto deve funcionar na maioria dos Sabores do Unix, BSD e Linux:

PATH=/usr/ucb:${PATH} ps aux | grep httpd | grep -v grep

Testado em:

  • SunOS 5.10 [daí o PATH=...]
  • Linux 2. 6. 32 (CentOS)
  • Linux 3. 0 (Ubuntu)
  • Darwin 11.2.0
  • FreeBSD 9.0-estável
  • Red Hat Enterprise Linux es release 4
  • Red Hat Enterprise Linux Server release 5
 6
Author: Johnsyweb, 2013-02-14 20:49:16

Apenas uma pequena adição: se adicionar a bandeira -c ao ps, não precisa de remover a linha que contém o processo grep com grep -v Depois. I. e.

ps acux | grep cron

É toda a tipagem de que necessita num sistema BSD-ish (isto inclui o MacOSX), pode deixar o {[[5]} de lado se necessitar de menos informação.

Num sistema onde a genética do nativo ps ponto de comando de volta para SysV, você usaria

ps -e |grep cron

Ou

ps -el |grep cron 

Para uma lista que contenha mais do que apenas pid e nome do processo. Claro que poderá seleccionar os campos específicos a imprimir com a opção -o <field,field,...>.

 5
Author: Tatjana Heuser, 2012-02-02 21:32:45

Juntando as várias sugestões, a versão mais limpa que consegui inventar (sem grep duvidoso que despoleta partes de palavras) é:

kill -0 $(pidof mysql) 2> /dev/null || echo "Mysql ain't runnin' message/actions"

O Kill-0 não mata o processo, mas verifica se existe e depois devolve verdadeiro, se não tiver o pidof no seu sistema, Guarde o pid quando iniciar o processo:

$ mysql &
$ echo $! > pid_stored

Depois no guião:

kill -0 $(cat pid_stored) 2> /dev/null || echo "Mysql ain't runnin' message/actions"
 4
Author: gletscher, 2014-04-04 19:20:15

Uso {[[0]} mas não sei se está presente em qualquer plataforma...
Quem pode confirmar o OSX?

 3
Author: olibre, 2012-02-02 18:10:34

Você deve saber o PID do seu processo.

Quando o lançar, o seu PID será gravado na variável $!. Grava este PID num ficheiro.

Então terá de verificar se este PID corresponde a um processo em execução. Aqui está um script esqueleto completo:

FILE="/tmp/myapp.pid"

if [ -f $FILE ];
then
   PID=$(cat $FILE)
else
   PID=1
fi

ps -o pid= -p $PID
if [ $? -eq 0 ]; then
  echo "Process already running."  
else
  echo "Starting process."
  run_my_app &
  echo $! > $FILE
fi

Baseado na resposta de peterh. O truque para saber se um dado PID está em execução está na instrução ps -o pid= -p $PID.

 1
Author: icarito, 2017-05-23 12:34:42

Esta abordagem pode ser usada no caso de os comandos 'ps', 'pidof' e rest não estarem disponíveis. Eu pessoalmente uso procfs muito frequentemente em minhas ferramentas/scripts/programas.

   egrep -m1  "mysqld$|httpd$" /proc/[0-9]*/status | cut -d'/' -f3
Uma pequena explicação para o que se passa.
  1. -m1 - processo de paragem na primeira partida
  2. "mysqld$ / httpd$" - grep irá corresponder às linhas que terminaram no mysqld ou no httpd
  3. /proc/[0-9] * - bash irá corresponder à linha que começou com qualquer número {[[8]}
  4. cortar-dividir a saída por separador ' / ' e extrair campo 3
 0
Author: Tom Lime, 2013-11-14 09:16:41
Isto imprime o número de processos cujo nome de base é "cromo-browser":
ps -e -o args= | awk 'BEGIN{c=0}{
 if(!match($1,/^\[.*\]$/)){sub(".*/","",$1)} # Do not strip process names enclosed by square brackets.
 if($1==cmd){c++}
}END{print c}' cmd="chromium-browser"

Se isto imprime "0", o processo não está a correr. O comando assume que o caminho do processo não contém espaço de quebra. Eu não testei isso com processos suspensos ou processos zumbis.

Testado usando gwak como a alternativa awk no Linux.

Aqui está uma solução mais versátil com algum uso de exemplo:

#!/bin/sh
isProcessRunning() {
if [ "${1-}" = "-q" ]; then
 local quiet=1;
 shift
else
 local quiet=0;
fi
ps -e -o pid,args= | awk 'BEGIN{status=1}{
 name=$2
 if(name !~ /^\[.*\]$/){sub(".*/","",name)} # strip dirname, if process name is not enclosed by square brackets.
 if(name==cmd){status=0; if(q){exit}else{print $0}}
}END{exit status}' cmd="$1" q=$quiet
}

process='chromium-browser'

printf "Process \"${process}\" is "
if isProcessRunning -q "$process" 
 then printf "running.\n"
 else printf "not running.\n"; fi

printf "Listing of matching processes (PID and process name with command line arguments):\n"
isProcessRunning "$process"
 0
Author: jarno, 2015-06-21 16:25:54
Aqui está a minha versão. Características:
  • verifica o nome exacto do programa (primeiro argumento da função). a procura por " mysql "não irá corresponder à execução de"mysqld"
  • procura argumentos do programa (segundo argumento da função)

Script:

#!/bin/bash

# $1 - cmd
# $2 - args
# return: 0 - no error, running; 1 - error, not running
function isRunning() {
    for i in $(pidof $1); do
        cat /proc/$i/cmdline | tr '\000' ' ' | grep -F -e "$2" 1>&2> /dev/null
        if [ $? -eq 0 ]; then
            return 0
        fi
    done
    return 1
}

isRunning java "-Djava.util.logging.config.file=logging.properties"
if [ $? -ne 0 ]; then
    echo "not running, starting..."
fi
 0
Author: Raigedas, 2018-02-01 20:18:01
Nenhuma das respostas funcionou para mim, por isso é minha.
process="$(pidof YOURPROCESSHERE|tr -d '\n')"
if [[ -z "${process// }" ]]; then
  echo "Process is not running."
else
  echo "Process is running."
fi

Explicação:

|tr -d '\n'

Isto remove o retorno de transporte criado pelo terminal. O resto pode ser explicado por este post.

 0
Author: Jeff Luyet, 2018-06-20 18:04:37

A seguinte função shell, sendo apenas baseada em comandos e opções padrão POSIX deve funcionar na maioria (se não em qualquer) dos sistemas Unix e linux. :

isPidRunning() {
  cmd=`
    PATH=\`getconf PATH\` export PATH
    ps -e -o pid= -o comm= |
      awk '$2 ~ "^.*/'"$1"'$" || $2 ~ "^'"$1"'$" {print $1,$2}'
  `
  [ -n "$cmd" ] &&
    printf "%s is running\n%s\n\n" "$1" "$cmd" ||
    printf "%s is not running\n\n" $1
  [ -n "$cmd" ]
}

$ isPidRunning httpd
httpd is running
586 /usr/apache/bin/httpd
588 /usr/apache/bin/httpd

$ isPidRunning ksh
ksh is running
5230 ksh

$ isPidRunning bash
bash is not running

Note que vai sufocar quando passar o duvidoso nome de comando "0]" e também vai falhar em identificar processos com um espaço embutido em seus nomes.

Note também que a solução mais votada e aceite exige opções não Portáteis ps e usa gratuitamente uma concha que é, apesar da sua popularidade, não é garantido estar presente em todas as máquinas Unix / Linux(bash)

 -1
Author: jlliagre, 2015-06-22 12:54:53