Em um script bash, desejo fazer o seguinte (em pseudo-código):
if [ a process exists with $PID ]; then
kill $PID
fi
Qual é a expressão apropriada para a declaração condicional?
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 akill -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 informakill
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/signalkill -0
, eu tenho que fazer o seguinte:kill -0 25667 ; echo $?
- e, se eu receber um0
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 é:
O problema com:
é 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:
e
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.
DISCUSSÃ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?
fonte
-p
é desnecessário, pelo menos nesse caso.ps $PID
tem exatamente o mesmo resultado.ou
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.fonte
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.ps
comando com-p $PID
pode fazer isso:fonte
Você tem duas maneiras:
Vamos começar procurando uma aplicação específica no meu laptop:
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:
Portanto, seu código será:
Segunda maneira : basta procurar algo no
/proc/$PID
diretório. Estou usando "exe" neste exemplo, mas você pode usar qualquer outra coisa.Portanto, seu código será:
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.
fonte
/proc/$PID/exe
não é um arquivo regular. Então,[ -f /proc/$PID/exe ]
sempre retornará umfalse
resultado. Tente[ -h /proc/$PID/exe ]
.Parece que você quer
que retornará quando
$pid
terminar.Caso contrário, você pode usar
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).fonte
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?
fonte
kill -9
. Isso acaba instantaneamente com o processo, sem chance de se limpar. Em vez disso, use okill
equivalente akill -15
. Se isso não funcionar, você deve descobrir o porquê e apenas como último recursokill -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.
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'.
fonte
Por exemplo, no GNU / Linux, você pode usar:
Ou algo como
e isso mostra o nome do aplicativo, apenas o nome sem ID.
fonte
pidof
não retorna um número negativo, pois um PID negativo não faz sentido e você não pode matarinit
, 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 valorPid
posteriormente) simplesmenteif pidof 'process_name'; then...
pidof
exemplo está cheio de mal-entendidos sobre como o bashtest
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.
fonte