ps para mostrar apenas processos que correspondam a mais de uma condição (AND)

1

De acordo com a página ps man:

Except as described below, process selection options are additive. The default selection is discarded, and then the selected processes are added to the set of processes to be displayed. A process will thus be shown if it meets any of the given selection criteria.

Acho que isso significa que as correspondências são "OR" ed, não "AND" ed.

Estou desenvolvendo meu próprio script de bloqueio que cria um diretório (mkdir mutex) e grava informações de PPID e PID em um arquivo nesse diretório. Uma das funções do script é limpar os arquivos de bloqueio obsoletos, fazendo o loop de todos os arquivos de bloqueio e extraindo $ PPID e $ PID. Em seguida, ele determina se um processo com PID $ PID e PPID $ PPID ainda está em execução.

No entanto, com ps estou obtendo todos processos que têm PPID $ PPID e também estou recebendo PID $ PID. Quero que ele mostre apenas o processo com pid $ PID e ppid $ PPID

Eu entendo que grep é intuitivamente útil aqui, mas existe um método "menos caro" para usar? Talvez outro utilitário relacionado ao processo?

procps-3.2.7-16.el5

    
por Felipe Alvarez 25.11.2014 / 01:23

3 respostas

0

Esta é uma solução da Shell que não requer utilitários externos além de ps

if [[ 'ps --pid $PID -oppid=' = $PPID ]]
then
   : still running
else
   : not running
fi
    
por 30.11.2014 / 03:53
0

Acabei de verificar, parece que o CentOS 6.6 pgrep não tem a opção -F , então isso não é aplicável. Vou deixar essa resposta aqui, pois pode ser útil em outros casos.

pgrep pode ser o que você quer:

-P, --parent ppid,...
      Only match processes whose parent process ID is listed.
-F, --pidfile file
      Read  PID's  from  file.  This option is perhaps more useful for
      pkill than pgrep.

Parece que pgrep com -F filtrará os PIDs para que correspondam aos do arquivo:

$ pgrep libvirtd
1343
18471
$ pgrep -F /var/run/libvirtd.pid -P 1
1343
$ echo -n 18471 > other-libvirtd.pid
$ pgrep -F other-libvirtd.pid -P 1
$ pgrep -F other-libvirtd.pid
18471
    
por 25.11.2014 / 03:56
0

Usando uma opção ps e filtragem adicional com grep ou awk é uma abordagem razoável.

Não passe a opção -o para ps e limite os campos aos que você precisa. Use um sinal de igual após cada nome de campo para suprimir a linha de cabeçalho. Se você não precisa do nome do comando, não inclua comm ou args , o que poderia incluir novas linhas (e em qualquer contexto sensível à segurança, se eles contiverem uma nova linha, verifique se o script faz algo sensato). Por exemplo, se você só precisa do PID e quer todos os processos que pertencem a um determinado grupo e estão sendo executados em um determinado TTY, então você pode coletar os PIDs com

pid_list=$(ps -t tty3 -o 'pid= gid=' | awk '$2 == 1234 || $2 == "somegroup"')

No seu caso, isso é um exagero. Existe um único processo que tem um determinado PID, então a condição -p $PID é toda a filtragem que você precisa. Recupere o PPID do processo por esse PID e compare-o com o valor esperado. ps não produzirá nada se não houver processo com esse PID.

read pid expected_ppid <"$pidfile"
actual_ppid=$(ps -o ppid= -p "$pid")
if [ "$actual_ppid" = "$expected_ppid" ]; then …

Lembre-se de que, se você encontrar um processo com as características corretas, poderá ser o mesmo processo ou um processo não relacionado, pois o processo esperado está morto há muito tempo e seu PID foi reutilizado.

    
por 25.11.2014 / 23:24

Tags