Como posso testar se um programa está sendo executado dentro de um script

3

Vamos supor que outro usuário tenha iniciado um processo bunzip e que eu tenha um script que gostaria de começar a executar depois que o bunzip terminar. Qual é a melhor maneira de verificar dentro do meu script que o processo bunzip terminou? Uma chamada para ps com o pid especificado? Um bunzip pgrep? Suponha que eu jogue meu script em um crontab que verifica a cada 5 minutos para ver se ele pode ser executado. Suponha também que não quero parar o bunzip, pois ele está funcionando há mais de uma hora e provavelmente levará outra hora para ser concluído.

Minha primeira reação seria usar algo como

if 'ps -p 12938'
    # bunzip is done, execute the code
fi 
    # exit

Mas, eu estou querendo saber se existe uma maneira melhor. Além disso, não tenho certeza de como é o cross-unix ps -pid.

    
por gabe. 08.09.2011 / 01:31

3 respostas

6

Sua aparente pergunta: testando a existência de um processo com um determinado PID

ps -p $pid é POSIX e deve funcionar em qualquer unix moderno não incorporado (não antiguidades ou Minix ou BusyBox ).

Uma maneira simples e portátil de testar se existe um processo por um determinado PID é kill -0 $pid . Isso só funciona se você puder enviar um sinal para o processo (o sinal 0 se comporta como um sinal que é sempre entregue, mas não tem efeito), significando que kill está sendo executado sob o UID efetivo do processo ou como raiz. Se kill estiver sendo executado como um usuário diferente, você poderá testar se ele sinaliza “nenhum tal processo” (ESRCH) ou “operação não permitida” (EPERM), mas a partir do shell isso requer saber como sua implementação formatará a mensagem de erro .

Seu design subjacente: testar se um processo foi concluído

O projeto proposto tem uma grande falha: como você sabe se esse PID é o processo bunzip pelo qual você estava esperando? Talvez bunzip tenha terminado e agora há outro processo com seu antigo PID. O único lugar em que você pode esperar com segurança na finalização de um processo está em seu pai.

Uma abordagem melhor seria acionar a existência do arquivo descompactado e a inexistência do arquivo compactado ou verificar se o arquivo descompactado não está aberto por nenhum processo (com lsof ).

    
por 08.09.2011 / 02:27
4

Não vejo nada de errado em usar ps, mas aqui está uma alternativa

if [ -e /proc/${PID} -a /proc/${PID}/exe ]
    % process active
else
    % process no longer active
fi
    
por 08.09.2011 / 02:38
1

Existem algumas opções.

  • Use ps e procure pelo PID. Você precisa conhecer os processos PID embora.
  • Use o ps e procure por bunzip, requer a visualização da linha de comando completa.
  • Use lsof e veja quando o arquivo de origem não está mais sendo acessado.
  • O mesmo, mas verifique se o arquivo descompactado ainda está sendo acessado.

Nenhum desses é realmente a prova de erros ou limpo.

A maneira mais fácil é tirar as mãos do usuário e escrever um script que realiza a descompactação e, em seguida, executa seu código.

Se isso não for possível, peça ao usuário para criar um script que crie um arquivo pid no disco enquanto o arquivo está sendo descompactado. Você pode então procurar pelo arquivo PID.

    
por 08.09.2011 / 02:02