What does the lsof -c flag filter out

lsof

lsof will show a table with the first column being the command name and each row, an open file. So to only show rows from a specific command, say "java", it would make sense to try lsof | grep ^java. This works, but I understand lsof has it's own flag to limit the output to only specific commands – -c. But when i try lsof -c java the output is totally different. The -c method only outputs about 10 lines whereas the grep method outputs several thousand lines.

So my question is — what else does lsof -c filter out?

Since the question got a downvote, I will elaborate. The reason for the question is that the grep method lsof | grep ^java should theoretically be the same output as lsof -c java. My reasoning is this —

lsof | grep ^java will only show lines that start with the letters "java" and the beginning of each line of lsof output is the name of the command that opened the file.

lsof -c java is supposed to only show files that are opened by the command that starts with the letters "java". The command name is at the beginning of each line of lsof output.

I don't know how to explain it any clearer than that.

To answer the comment from yoonix, this is what the lsof man page says about the -c flag. You should actually read it before suggesting that I read it for an answer:

   -c c     selects  the  listing of files for processes executing the command that begins with the characters of c.  Multiple commands may be
            specified, using multiple -c options.  They are joined in a single ORed set before participating in AND option selection.

            If c begins with a `^', then the following characters specify a command name whose processes are to be ignored (excluded.)

            If c begins and ends with a slash ('/'), the characters between the slashes  are  interpreted  as  a  regular  expression.   Shell
            meta-characters  in  the regular expression must be quoted to prevent their interpretation by the shell.  The closing slash may be
            followed by these modifiers:

                 b    the regular expression is a basic one.
                 i    ignore the case of letters.
                 x    the regular expression is an extended one
                      (default).

            See the lsof FAQ (The FAQ section gives its location.)  for more information on basic and extended regular expressions.

            The simple command specification is tested first.  If that test fails, the command regular expression is applied.  If  the  simple
            command  test  succeeds,  the command regular expression test isn't made.  This may result in ``no command found for regex:'' mes‐
            sages when lsof's -V option is specified.

Best Answer

The command lsof | grep php will filter all the lines from the output of lsof command containing php as anywhere in the line as a substring like below:

apache2 26964 /usr/lib/php/20151012/wddx.so
apache2 26964 /usr/lib/php/20151012/tokenizer.so
apache2 26964 /usr/lib/php/20151012/sysvshm.so
apache2 26964 /usr/lib/php/20151012/sysvsem.so

Whereby lsof -c php selects the listing of files for processes executing the command that begins with the characters php:

php-fpm7. 1775 /lib/x86_64-linux-gnu/libpthread-2.23.so
php-fpm7. 1775 /lib/x86_64-linux-gnu/libc-2.23.so
php-fpm7. 1775 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
php-fpm7. 1775 /lib/x86_64-linux-gnu/libssl.so.1.0.0
php-fpm7. 1775 /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.4

Hope the reason of mismatch is clear from the given example.