Como posso determinar se um processo está em execução ou não e depois fazer com que um script bash execute algumas coisas com base nessa condição?
Por exemplo:
se o processo
abc
estiver em execução, faça issose não estiver em execução, faça isso.
Como posso determinar se um processo está em execução ou não e depois fazer com que um script bash execute 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.
Respostas:
Um script bash para fazer algo assim seria algo como 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á em execução.
Ou você só pode verificar se o programa não está sendo executado assim:
if ! pgrep -x "gedit" > /dev/null
then
echo "Stopped"
fi
/dev/null
: "/ dev / null redireciona a saída padrão do comando para o dispositivo nulo, que é um dispositivo especial que descarta as informações gravadas nele" ... o uso 0
redireciona a saída do comando para um arquivo chamado 0
. Nesse caso, aconselho que você se sinta mais confortável > /dev/null
- você o verá em qualquer lugar, pois é a maneira padrão / adequada de descartar a saída.
-x
parâmetro para pgrep
que ele procure a aplicação exata, caso contrário, a correção será falsa se encontrar a mesma string dentro do nome de outro aplicativo. Passei apenas 1 hora para descobrir isso.
! pgrep
Qualquer solução que use algo parecido ps aux | grep abc
ou com pgrep abc
defeito.
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 coincida abc
. Qualquer usuário pode criar e executar facilmente um executável chamado abc
(ou que contenha abc
algum lugar em seu nome ou argumentos), causando um falso positivo para o seu teste. Existem várias opções que você pode aplicar para ps
, grep
e pgrep
para restringir a busca, mas você ainda não terá um teste confiável.
Isso depende do que você precisa para o teste.
É para isso que servem o init e o upstart. Eles iniciarão o serviço e garantirão que seu pid seja armazenado em um arquivo de pid. Tente iniciar o serviço novamente (via init ou upstart) e ele verificará o pidfile e inicie-o se ele não estiver lá ou aborte se já estiver em execução. Isso ainda não é 100% confiável, mas é o mais próximo possível.
Consulte Como posso verificar se meu servidor de jogos ainda está em execução ... para outras soluções.
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 a Bash FAQ 45 para outras formas de bloqueio.
pgrep
ou ps
é perfeitamente adequado e sua abordagem parece um exagero. Se você estiver escrevendo um script para distribuição pública, deve escrevê-lo da maneira mais segura possível.
rm
comando é executado. Portanto, desde que termine após a armadilha ter sido configurada, a trava deverá desaparecer.
Isto é 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á sendo executado, caso contrário, não é.
Leitura relacionada:
Bash Scripting :: Comparações de strings
Manuais do Ubuntu pgrep
pgrep
tem o mesmo "recurso" de 15 caracteres limite mencionado anteriormente, assim, por exemplo, pgrep gnome-power-manager
também falham
-x
opção do pgrep : " Corresponde apenas aos processos cujo nome (ou linha de comando se -f for especificado) corresponde exatamente ao padrão."
Normalmente, tenho um pidof -x $(basename $0)
em meus scripts para verificar se ele já está em execução.
Pensando na ideia de @ 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 / outra. Por exemplo, aqui está um com um processo em execução (meu navegador chrome, cujo nome do 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
$
Nenhuma das soluções "simples" funcionou para mim porque o binário que preciso verificar não está instalado em todo o sistema; portanto, tenho que verificar com o caminho, o que, por sua vez, requer o uso da ps -ef | grep
abordagem:
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
A primeira coisa que veio à minha mente para o seu problema:
ps aux | grep -i abc
mostrará os detalhes do processo, se estiver em execução. Você pode corresponder ao número de linhas ou tempo durante o qual está sendo executado e comparar com zero ou qualquer outra manipulação. Quando você executa o comando acima, ele mostra pelo menos uma linha de saída, ou seja, detalhes sobre o processo criado pelo comando grep. Portanto, cuide disso.
Isso deve fazer como um simples hack. Coloque-o no script bash e veja se é útil.
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.
Eu 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 sendo executado ou não, estou executando o CentOS 7.
A resposta da @ geirha apenas garante que uma instância ainda não esteja em execução antes de iniciar outra. Esta não era a pergunta original, a questão original era verificar se um processo está sendo executado ou não.
Aqui está o que funcionou para mim:
Digamos que meu processo tenha a string "Jane" no nome do processo. Isso descobrirá se está sendo executado 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
## 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 relata que lxpanel
está sendo executado mesmo quando está extinto (zumbi); Para obter um processo ativo e em execução, precisamos usar ps
egrep
Em 23 de setembro de 2016, o pgrep parece exigir a opção "-x" para que o script de 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. Desfrutar!
#!/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
zombie
processo '(não é o que eu descreveria como um processo "em execução"). Uma lista completa do que osSTAT
valores da coluna, na saída deps
, indica está aqui para aqueles que desejam escrever uma resposta que acomode isso ou editar seus próprios.