Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

On CentOS 7.0.1406 I get differing output when running

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

than when I run

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

The latter returns nothing; the former what I would expect. I was under the impression that comm was an alias for command. Could someone please explain the difference?

share|improve this question
    
You might also want to look at pgrep for stuff like this – Eric Renouf Jan 25 at 13:25
up vote 5 down vote accepted

They are not aliases. Command outputs the full command and comm only the command name, so it is possible that the outputs are different. It all depends on what you want to extract the grep command.

An example:

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

and the output for the following is empty:

ps -A -o pid,comm | grep 9600

The string 9600 is part of the complete command but the command name.

command, and cmd are aliases to args, with prints the command with all its arguments as string. comm is a different sorting code that prints only the executable name. Manpage snippet:

   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).
share|improve this answer

On Linux, with the procps(-ng) (at least) implementation of ps (as is the case on CentOS):

  • comm is the process name. That's retrieved from /proc/<pid>/stat and is limited (truncated) to 16 bytes. That's usually the basename of the first argument to the last execve() system call that the process (or any of its ancestors) made, unless it's a kernel thread in which case it's the kernel thread's name like watchdog/0 or rcu_sched or the process has changed it with prctl(PR_SET_NAME). It's the CMD field in the ps output.
  • command aka args is the concatenation of the arguments passed to the latest execve() system call that the process (or any of its ancestors) made. If there was no argument (like for kernel threads), ps uses [process-name] instead (the process name as described above enclosed in square brackets). That's retrieved from /proc/<pid>/cmdline. That's the CMD field in the ps -f output. Note that for scripts, execve() is internally called again after resolution of the she-bang. Processes can also alter that value by overwriting the argv[] strings it received.

POSIX specifies comm (meant to be argv[0]) and args (the arg list as a string, though doesn't say how that list is to be represented (joined with spaces?)), not command. So the procps implementation is not compliant as comm is not the argv[0] there. Solaris, a certified implementation does have argv[0] for comm and has fname for the equivalent of procps' comm (as the CMD column in ps output).

Examples:

  • Relation to 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 overwriting both its process name and arg list:

    $ perl -e '$0 = "new name"; system("ps -p $$ -o comm,command")'
    COMMAND         COMMAND
    new name        new name
    
  • Behaviour for 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 ends up being executed with a different arg list, but the process name remains test-script. Here the argv[0] that sh receives is /bin/sh. On some systems, it's test-script instead.

  • On the note about ancestors:

    $ ((((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
    

    The 2314{6,7,8,9} processes never executed any command, they inherit their process name and arg list from their parent (4109) which executed /bin/zsh.

    23150 itself initially had a process name of zsh like the others, but it changed to ps upon executing /bin/ps.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.