Melhor maneira de identificar / identificar processos para matá-los mais tarde?

3

Nos meus scripts de inicialização do Linux, quando inicio um processo como (openvpn usado para este exemplo, mas a questão é geral para qualquer processo);

openvpn --config /etc/myserver.conf

qual é a melhor maneira de encontrá-lo e ter 100% de certeza de que é o processo certo e matá-lo na seção de parada? Eu normalmente uso coisas como:

pid=$(ps -efww | grep -v grep | grep openvpn | grep /etc/myserver.conf | awk '{print $2}')

Claro que funciona quase o tempo todo, mas às vezes há problemas com a correspondência acidental de processos com quase o mesmo nome (por exemplo, myserver.conf-new), então estou procurando uma abordagem melhor.

  • Alguns processos têm uma maneira de armazenar o pid em algum lugar, tudo bem, mas geralmente eu sou cético em relação a matar processos baseados exclusivamente em um pid em um arquivo em algum lugar.
  • O Solaris tem projetos , não são todos rosas na minha experiência limitada, porque você precisa configure o / etc / projects primeiro, mas facilita marcar e depois localizar processos.
  • Talvez usando o ambiente, como configurar uma variável de ambiente como (MYID = myserver) e, em seguida, procurá-la com ps e -ef | grep MYID=myserver ? Ainda pode sofrer o mesmo problema com correspondência acidental.

Eu gostaria que houvesse algo fácil como:

launch --tag myserver openvpn --config /etc/myserver.conf

e

pgrep --tag myserver
    
por Steve Kehlet 26.05.2011 / 20:16

4 respostas

5

Obrigado @Iain, @KyleSmith e @ M_1 pelas suas respostas e por me ajudar a começar a trabalhar com o Server Fault. Se eu tivesse mais rep aqui, eu teria +1 vocês. (Edit: agora eu tenho rep, + 1s ao redor).

Eu vou responder a minha própria pergunta porque eu encontrei algo que faz o que eu estava procurando: uma solução geral que evita a correspondência de padrões imprecisos com ps, e não usa arquivos pid. É completamente subjetivo que este seria o "melhor" caminho porque obviamente há uma história longa e bem-sucedida no unix de usar arquivos pid, no entanto, isso foi algo que eu disse explicitamente que não gostei por várias razões, e eles são: complicado criar adequadamente, diferente para cada software, feito de forma diferente em cada distribuição, pode ser obsoleto / substituído, e inerentemente não representa necessariamente o que realmente está acontecendo. Eu prefiro usar algum tipo de marcação de processo, perguntar ao kernel e obter respostas reais.

Exemplo reduzido:

#!/bin/sh
_TAG=d726cc7fa57a308afdc057b228a13f6d
case "$1" in
start)
  _TAG=$_TAG ./self-backgrounding-process
  _TAG=$_TAG ./non-self-backgrounding-process &
  ;;
stop)
  pids=$(grep -l "\b_TAG=$_TAG\b" /proc/*/environ | cut -d/ -f3)
  [ -n "$pids" ] && kill $pids
  ;;
esac

Os pontos principais são:

  • usando um md5sum (algo muito improvável de ser correspondido acidentalmente) para a tag
  • usando uma tag diferente no script de inicialização de cada serviço
  • consultando / proc / * / environ para obter uma lista precisa de processos em execução / relevantes / marcados
  • usando grep com \ b para corresponder aos limites das palavras para garantir uma correspondência exata

Não tenho certeza se gosto de poluir o ambiente, mas não sei de nenhuma outra forma (por exemplo, projetos do Solaris) para marcar um processo do Linux de uma maneira arbitrária que possa solicitar ao kernel para mais tarde. Pelo menos, / proc / < pid > / environ aparece como reflete o ambiente na inicialização e não é afetado por quaisquer alterações que o processo possa fazer após , o que sugere que isso deve ser confiável, no entanto, há a chance de que isso possa mudar inesperadamente. Isso pode ou não funcionar fora do Linux, dependendo da implementação do sistema operacional / proc e grep.

Acho que vou tentar por um tempo e ver o que acontece.

    
por 27.05.2011 / 19:59
3

Não tenha medo de pidfiles, eles são testados e verdadeiros e normalmente pertencem à raiz! :)

A maioria das distribuições usa uma função padrão ou binário para iniciar daemons e armazenar o PID resultante em um arquivo. No Debian, por exemplo, você tem o start-stop-daemon com a opção --pidfile . Outras distribuições possuem /etc/rc.d/init.d/functions (ou similar) que são usadas para iniciar daemons. Verifique alguns dos scripts de inicialização mais genéricos incluídos na sua distribuição.

    
por 26.05.2011 / 20:33
2

Uma boa ideia seria usar um script simples de wrapper que grava um arquivo lock / pid desse aplicativo (comumente usado em servidores da Web ou bancos de dados) e use esse arquivo para matar exatamente esse processo, se necessário.

    
por 26.05.2011 / 20:24
2

Para openvpn, em particular, você pode usar a opção de linha de comando --writepid /path/to/file , e.

/usr/sbin/openvpn --writepid /var/run/openvpn/server.pid  --config /etc/myserver.conf ...

O qual gravará o PID do processo principal openvpn no arquivo nomeado.

Em geral, você pode envolver seu programa em um pequeno script e usar a variável bash $! builtin para gravar o pid em um arquivo

#!/bin/bash
yourcommand &
echo $! >/path/to/pid.file
    
por 26.05.2011 / 20:45