Respostas:
Para verificar a existência de um processo, use
kill -0 $pid
Mas, como o @unwind disse, se você vai matá-lo de qualquer maneira, apenas
kill $pid
ou você terá uma condição de corrida.
Se você deseja ignorar a saída de texto kill
e fazer algo com base no código de saída, pode
if ! kill $pid > /dev/null 2>&1; then
echo "Could not send SIGTERM to process $pid" >&2
fi
kill
é um pouco errado, pois não necessariamente mata o processo. Apenas envia um sinal ao processo. kill $PID
é equivalente a kill -15 $PID
, que envia o sinal 15, SIGTERM para o processo, que é uma instrução para finalizar. Não há sinal 0, é um valor especial que informa kill
apenas para verificar se um sinal pode ser enviado ao processo, o que é, na maioria dos casos, mais ou menos equivalente a verificar se ele existe. Veja linux.die.net/man/2/kill e linux.die.net/man/7/signal
kill -0
, eu tenho que fazer o seguinte: kill -0 25667 ; echo $?
- e, se eu receber um 0
retorno, o processo com esse PID pode ser morto; e se o processo PID (digamos) não existir, o $?
será 1
, indicando uma falha. Isso está correto?
A melhor maneira é:
if ps -p $PID > /dev/null
then
echo "$PID is running"
# Do something knowing the pid exists, i.e. the process with $PID is running
fi
O problema com:
kill -0 $PID
é que o código de saída será diferente de zero, mesmo se o pid estiver em execução e você não tiver permissão para eliminá-lo. Por exemplo:
kill -0 1
e
kill -0 $non-running-pid
tenha um código de saída indistinguível (diferente de zero) para um usuário normal, mas o processo init (PID 1) certamente está em execução.
As respostas que discutem as condições de matança e raça são exatamente corretas se o corpo do teste for uma "matança". Eu vim procurando pelo general " como você testa a existência de PID no bash ".
O método / proc é interessante, mas, em certo sentido, quebra o espírito da abstração do comando "ps", ou seja, você não precisa procurar no / proc porque, e se Linus decidir chamar o arquivo "exe" de outra coisa?
-p
é desnecessário, pelo menos nesse caso. ps $PID
tem exatamente o mesmo resultado.
if [ -n "$PID" -a -e /proc/$PID ]; then
echo "process exists"
fi
ou
if [ -n "$(ps -p $PID -o pid=)" ]
No último formulário, -o pid=
é um formato de saída para exibir apenas a coluna de ID do processo sem cabeçalho. As aspas são necessárias para que o operador de sequência não vazia -n
forneça um resultado válido.
if ps -p"$PID" -o "pid=" >/dev/null 2>&1; then echo "Process is running..."; fi
ps
opções e os recursos tendem a variar entre as plataformas, por isso ainda não é totalmente portátil.
$PID
estiver vazio, [ -e /proc/$PID ]
ainda retornará verdadeiro, pois o /proc/
diretório ainda existe.
Você tem duas maneiras:
Vamos começar procurando uma aplicação específica no meu laptop:
[root@pinky:~]# ps fax | grep mozilla
3358 ? S 0:00 \_ /bin/sh /usr/lib/firefox-3.5/run-mozilla.sh /usr/lib/firefox-3.5/firefox
16198 pts/2 S+ 0:00 \_ grep mozilla
Todos os exemplos agora procurarão pelo PID 3358.
Primeira maneira : Execute "ps aux" e grep para o PID na segunda coluna. Neste exemplo, procuro o Firefox e, em seguida, o PID:
[root@pinky:~]# ps aux | awk '{print $2 }' | grep 3358
3358
Portanto, seu código será:
if [ ps aux | awk '{print $2 }' | grep -q $PID 2> /dev/null ]; then
kill $PID
fi
Segunda maneira : basta procurar algo no /proc/$PID
diretório. Estou usando "exe" neste exemplo, mas você pode usar qualquer outra coisa.
[root@pinky:~]# ls -l /proc/3358/exe
lrwxrwxrwx. 1 elcuco elcuco 0 2010-06-15 12:33 /proc/3358/exe -> /bin/bash
Portanto, seu código será:
if [ -f /proc/$PID/exe ]; then
kill $PID
fi
BTW: o que há de errado com kill -9 $PID || true
?
EDITAR:
Depois de pensar nisso por alguns meses .. (cerca de 24 ...), a ideia original que dei aqui é um truque agradável, mas altamente não transportável. Embora ensine alguns detalhes de implementação do Linux, ele não funcionará no Mac, Solaris ou * BSD. Pode até falhar em futuros kernels do Linux. Por favor - use "ps" como descrito em outras respostas.
/proc/$PID/exe
não é um arquivo regular. Então, [ -f /proc/$PID/exe ]
sempre retornará um false
resultado. Tente [ -h /proc/$PID/exe ]
.
Parece que você quer
wait $PID
que retornará quando $pid
terminar.
Caso contrário, você pode usar
ps -p $PID
para verificar se o processo ainda está ativo (isso é mais eficaz do que kill -0 $pid
porque funcionará mesmo se você não possuir o pid).
pid 123 is not a child of this shell
Eu acho que é uma péssima solução, que se abre para condições de corrida. E se o processo morrer entre o seu teste e a sua chamada para matar? Então matar falhará. Então, por que não apenas tentar matar em todos os casos e verificar seu valor de retorno para descobrir como foi?
kill -9
. Isso acaba instantaneamente com o processo, sem chance de se limpar. Em vez disso, use o kill
equivalente a kill -15
. Se isso não funcionar, você deve descobrir o porquê e apenas como último recurso kill -9
.
aqui eu guardo o PID em um arquivo chamado .pid (que é como like / run / ...) e só executo o script se ele ainda não estiver sendo executado.
#!/bin/bash
if [ -f .pid ]; then
read pid < .pid
echo $pid
ps -p $pid > /dev/null
r=$?
if [ $r -eq 0 ]; then
echo "$pid is currently running, not executing $0 twice, exiting now..."
exit 1
fi
fi
echo $$ > .pid
# do things here
rm .pid
nota: existe uma condição de corrida, pois não verifica como esse pid é chamado. se o sistema for reiniciado e o .pid existir, mas for usado por um aplicativo diferente, isso poderá gerar 'consequências imprevistas'.
Por exemplo, no GNU / Linux, você pode usar:
Pid=$(pidof `process_name`)
if [ $Pid > 0 ]; then
do something
else
do something
fi
Ou algo como
Pin=$(ps -A | grep name | awk 'print $4}')
echo $PIN
e isso mostra o nome do aplicativo, apenas o nome sem ID.
pidof
não retorna um número negativo, pois um PID negativo não faz sentido e você não pode matar init
, portanto, seu condicional não faz sentido (além disso, você precisaria escapar do >
para impedir que ele redirecionasse). Você deseja verificar se há um resultado vazio, mas é claro que, como qualquer ferramenta decente, pidof
define um código de saída para informar se funcionou; portanto, a solução adequada é if Pid=$(pidof 'process_name'); then ...
ou (se você não precisar do valor Pid
posteriormente) simplesmenteif pidof 'process_name'; then...
pidof
exemplo está cheio de mal-entendidos sobre como o bash test
funciona. gnu.org/software/bash/manual/html_node/…
O código abaixo verifica se meu processo está em execução; caso contrário, não faça nada.
vamos verificar novas mensagens do Amazon SQS a cada hora apenas e somente se o processo não estiver em execução.
#!/bin/bash
PID=$(ps aux | grep '/usr/bin/python2.7 manage.py SES__boto3_sqs_read' | grep -v grep | awk '{print $2}')
if [[ -z $PID ]]; then
/usr/bin/python2.7 /home/brian/djcode/proyectoONE/manage.py SES__boto3_sqs_read
else
echo "do nothing, just smile =)"
fi
exit $?