Estou escrevendo um script Perl que analisa arquivos de log para coletar PIDs e verifica se esse PID está em execução. Estou tentando pensar na melhor maneira de fazer essa verificação. Obviamente, eu poderia fazer algo como:
system("ps $pid > /dev/null") && print "Not running\n";
No entanto, eu preferiria evitar a chamada do sistema, se possível. Por isso, pensei que poderia usar o /proc
sistema de arquivos (portabilidade não é uma preocupação, isso sempre estará sendo executado em um sistema Linux). Por exemplo:
if(! -d "/proc/$pid"){
print "Not running\n";
}
Isso é seguro? Posso sempre assumir que, se não houver /proc/$pid/
diretório, o PID associado não está sendo executado? Espero que sim, já que o ps
próprio AFAIK obtém suas informações de /proc
qualquer maneira, mas como isso é para código de produção, quero ter certeza.
Portanto, pode haver casos em que um processo em execução não possui /proc/PID
diretório ou onde /proc/PID
existe um diretório e o processo não está em execução? Existe algum motivo para preferir a análise em ps
vez de verificar a existência do diretório?
fonte
kill
função perl usando o sinal 0, que não mata, mas diz se você pode fazê-lo (ou seja, você precisa de permissão para sinalizar esse processo).kill -0
é o melhor), isso apenas informa se existe um processo em execução com o PID especificado . Ele não informa se o processo ainda estará em execução um milissegundo mais tarde e não informa se o processo é o que você está interessado ou se um processo não relacionado foi atribuído ao mesmo PID após a morte do processo interessante . Quase sempre é um erro testar se um determinado PID está sendo executado : há muito poucas circunstâncias em que isso não é propenso a condições de corrida.Respostas:
A função perl
kill(0,$pid)
pode ser usada.Se o código de retorno for 1, o PID existe e você pode enviar um sinal para ele.
Se o código de retorno for 0, será necessário verificar $ !. Pode ser EPERM (permissão negada), o que significa que o processo existe ou ESRCH; nesse caso, o processo não existe.
Se o seu código de verificação estiver em execução
root
, você poderá simplificar isso apenas verificando o código de retorno do kill; 0 => erro, 1 => okPor exemplo:
Isso pode ser transformado em uma função simples
fonte
if (!kill(0,$pid) && $! =~ /No such process/){ exit; }
ou algo parecido. Eu gosto mais da suaErrno
solução, obrigado. Embora eu provavelmente vá com isso, esperarei um pouco para que alguém possa responder à pergunta subjacente do Linux./proc
estiver montado, em seguida, todos os PID visível no espaço de nomes estarão presentes, para que o seu-d /proc/$pid
teste iria trabalhar ... mas envolve sair para o sistema de arquivos em vez de usar as chamadas do sistema nativas.system
chamada" - ou seja, uma chamada para asystem
função em si, não uma "chamada do sistema" . O último você não pode evitar, mas o primeiro você certamente pode. Faz sentido agora!/proc/PID
kill 0
/proc
/proc
ps
top
lsof
) e acredito que não há garantia de que ela exista (isto é, não é exigida pelo POSIX). E, a menos que o sistema seja completamente mangueira,kill
funcionará./proc
requer a leitura do diretório raiz para localizar o/proc
sistema de arquivos. Isto é verdade para qualquer tentativa de acessar qualquer arquivo por um caminho absoluto, incluindo coisas/bin
,/etc
e/dev
. Isso acontece com tanta frequência que o diretório raiz certamente fica armazenado em cache na memória durante toda a vida útil (tempo de atividade) do sistema, portanto, essa etapa pode ser realizada sem nenhuma E / S de disco. E, uma vez que você tenha o inode/proc
, tudo o que acontece fica na memória./proc
? Comstat
,open
,readdir
, etc., que são sistema nativo chama cada bocado tanto quantokill
.A pergunta fala sobre um processo em execução. Esta é uma frase escorregadia. Se você realmente deseja testar se o processo está em execução (por exemplo, na fila de execução; talvez o processo atual em alguma CPU; não esteja em espera, em espera ou parado), pode ser necessário fazer ae ler a saída ou observar . Mas não vejo nenhuma sugestão em sua pergunta ou comentário de que você esteja preocupado com isso.
ps PID
/proc/PID/stat
O elefante na sala, no entanto, é que um processo de zumbi 2 pode ser difícil de distinguir de um processo que está vivo e bem.
kill 0
trabalha em um zumbi e existe. Você pode identificar zumbis com as técnicas listadas no parágrafo anterior (executando e lendo a saída ou examinando ). Meu ocasional (ou seja, não muito completo) teste muito rápido e sugere que você também pode fazer isso, fazendo uma ou on , ou - estes irão falhar em zumbis. (No entanto, eles também falharão nos processos que você não possui.)/proc/PID
ps PID
/proc/PID/stat
readlink
lstat
/proc/PID/cwd
/proc/PID/root
/proc/PID/exe
____________
1 se o
-f
( f opção orce) não funcionar, tente-l
( l Azy).2 ou seja, um processo que saiu / morreu / terminou, mas cujo pai ainda não fez a
wait
.fonte
kill(2)
manual indique diretamente o comportamento que você apontou, mas aperlfunc
página de manual indica . Vou enviar um email para Michael Kerrisk para ver o que ele tem a dizer sobre a página de manual do sistema.kill(2)
sobre permissões para "enviar" o sinal 0. #kill(2)
manual (ainda não a vejo on-line): "Se sig for 0, nenhum sinal será enviado, mas ainda serão realizadas verificações de existência e permissão; isso pode ser usado para verificar a existência de um ID do processo ou ID do grupo de processos que o chamador está autorizado a sinalizar. "