ps - qual é a diferença entre o comando -o comm e -o?

4

No CentOS 7.0.1406 eu recebo saída diferente ao executar

ps -A -o pid,command | grep [r]esque

do que quando corro

ps -A -o pid,comm | grep [r]esque

O último não retorna nada; o primeiro o que eu esperaria. Fiquei com a impressão de que comm era um alias para command . Alguém poderia explicar a diferença?

    
por Pete Coward 25.01.2016 / 14:02

2 respostas

5

Eles não são aliases. Comando gera o comando completo e comunica apenas o nome do comando, portanto, é possível que as saídas sejam diferentes. Tudo depende do que você deseja extrair o comando grep.

Um exemplo:

$ ps -A -o pid,command | grep 9600
376 /sbin/agetty --keep-baud 115200 38400 9600 ttyS0 vt220

e a saída para o seguinte está vazia:

ps -A -o pid,comm | grep 9600

A string 9600 é parte do comando complete, mas o nome do comando.

command e cmd são aliases para args , com o comando prints com todos os seus argumentos como string. comm é um código de classificação diferente que imprime apenas o nome do executável. Snippet de página:

   args      COMMAND command with all its arguments as a string.

   cmd       CMD    see args. (alias args, command).

   comm      COMMAND command name (only the executable name).

   command   COMMAND see args. (alias args, cmd).
    
por 25.01.2016 / 14:15
2

No Linux, com a implementação procps (-ng) (pelo menos) de ps (como é o caso do CentOS):

  • comm é o nome do processo. Isso é recuperado de /proc/<pid>/stat e é limitado (truncado) a 16 bytes. Geralmente é o nome de base do primeiro argumento para a última chamada de sistema execve() que o processo (ou qualquer um de seus ancestrais) fez, a menos que seja um encadeamento de kernel, caso em que é o nome do encadeamento do kernel como watchdog/0 ou rcu_sched ou o processo mudou com prctl(PR_SET_NAME) . É o campo CMD na saída ps .
  • command também conhecido como args é a concatenação dos argumentos passados para a chamada de sistema execve() mais recente que o processo (ou qualquer um de seus antecessores) fez. Se não houver nenhum argumento (como para encadeamentos do kernel), ps usa [process-name] (o nome do processo, conforme descrito acima, entre colchetes). Isso é recuperado de /proc/<pid>/cmdline . Esse é o campo CMD na saída ps -f . Observe que, para scripts, execve() é chamado internamente novamente após a resolução do she-bang. Os processos também podem alterar esse valor sobrescrevendo as sequências de caracteres argv [] recebidas.

POSIX especifica comm (significando argv[0] ) e args (a lista arg como uma string, embora não diga como essa lista deve ser representada (unida a espaços?)), não command . Portanto, a implementação de procps não é compatível, pois comm não é o argv [0] lá. O Solaris, uma implementação certificada, tem argv [0] para comm e tem fname para o equivalente de procps ' comm (como a coluna CMD em ps output).

Exemplos:

  • Relação com execve() :

    $ ln -s /bin/sleep very-long-alias-for-sleep
    $ strace -e execve bash -c 'exec -a different-argv0 ./././very-long-alias-for-sleep 12' &
    execve("/bin/bash", ["bash", "-c", "exec -a different-argv0 ./././ve"...], [/* 52 vars */]) = 0                                                  10:56
    execve("/home/stephane/././very-long-alias-for-sleep", ["different-argv0", "12"], [/* 51 vars */]) = 0
    $ ps -o comm,command
    COMMAND         COMMAND
    [...]
    very-long-alias different-argv0 12
    [...]
    
  • perl sobrescrevendo o nome do processo e a lista de argumentos:

    $ perl -e '$0 = "new name"; system("ps -p $$ -o comm,command")'
    COMMAND         COMMAND
    new name        new name
    
  • Comportamento para scripts:

    $ cat test-script
    #! /bin/sh -e
    ps -o comm,command -p "$$"
    exit
    $ strace -e execve ./test-script arg
    execve("./test-script", ["./test-script", "arg"], [/* 52 vars */]) = 0
    COMMAND         COMMAND
    test-script     /bin/sh -e ./test-script arg
    

    /bin/sh acaba sendo executado com uma lista de argumentos diferente, mas o nome do processo permanece test-script . Aqui, o argv[0] que sh recebe é /bin/sh . Em alguns sistemas, é test-script .

  • Na nota sobre ancestrais:

    $ ((((ps -o pid,comm,command;:);:);:);:)
      PID COMMAND         COMMAND
     4109 zsh             /bin/zsh
    23146 zsh             /bin/zsh
    23147 zsh             /bin/zsh
    23148 zsh             /bin/zsh
    23149 zsh             /bin/zsh
    23150 ps              ps -o pid,comm,command
    

    Os processos 2314 {6,7,8,9} nunca executaram nenhum comando, eles herdam o nome do processo e a lista de argumentos do pai (4109) que executou / bin / zsh.

    O próprio 23150 inicialmente tinha um nome de processo de zsh como os outros, mas mudou para ps ao executar /bin/ps .

  • use -o 'comm' para distinguir os encadeamentos por seus nomes:

    $ ps -T -o pid,tid,pcpu,bsdtime,comm,command -C firefox.real | sort -k3nr
      # result is sorted by third column '%CPU'
    10743 10743  4.9  14:44 firefox.real    /usr/bin/firefox.real --private-window
    10743 10775  0.3   1:01 Compositor      /usr/bin/firefox.real --private-window
    10743 10750  0.0   0:00 Gecko_IOThread  /usr/bin/firefox.real --private-window
    10743 10751  0.0   0:16 Timer           /usr/bin/firefox.real --private-window
    10743 10752  0.0   0:00 Link Monitor    /usr/bin/firefox.real --private-window
    10743 10753  0.0   0:06 Socket Thread   /usr/bin/firefox.real --private-window
    10743 10755  0.0   0:00 JS Watchdog     /usr/bin/firefox.real --private-window
    10743 10756  0.0   0:04 JS Helper       /usr/bin/firefox.real --private-window
    ...
      PID   TID %CPU   TIME COMMAND         COMMAND
    
por 25.01.2016 / 17:58

Tags