Please explain the -f option in pgrep

commandcommand linegrepprocess

man pgrep says the following about -f option:

   -f     The  pattern  is normally only matched against the process name.
              When -f is set, the full command line is used.

What does it mean to say the full command line is used?

Best Answer

It means that without -f, pgrep only searches for the provided regexp in the command names, while with -f it searches it in their arguments (where the first argument (argv[0]) is not necessarily the same as the command name).

$ sleep 2000 &
[1] 15768
$ pgrep 2000
$ pgrep -f 2000
15768

And if we cause argv[0] to be different from the command name (on Linux as seen in /proc/$pid/stat) as when using zsh's ARGV0:

$ ARGV0=foo sleep 2000 &
[2] 15881
$ ps -fp $!
UID        PID  PPID  C STIME TTY          TIME CMD
chazelas 15881 13126  0 19:55 pts/1    00:00:00 foo 2000
$ ps -o comm= $!
sleep
$ awk '{print $2}' /proc/$!/stat
(sleep)
$ pgrep foo
$ pgrep sleep
15881
$ pgrep -f sleep
$ pgrep -f foo
15881

There's a lot of potential confusion regarding process name on Unix and Linux. There are 3 attributes of a process that could claim being the process name:

  • The base name of the executable that was passed to the last execve(2) system call that the process made. On Linux, that is used to initialise the process name, as reported by ps or found in /proc/$pid/stat. However, it should be noted that on Linux, it can be changed using prctl(PR_SET_NAME...).
  • any path to the executable that is currently mmaped for execution in the process and preferably the path as it was invoked (for scripts, that would be the path provided in the shebang line for instance). On Linux, you can get it with a readlink or /proc/$pid/exe. That one, you can't change without calling another execve (though you could in theory load a new executable in memory and execute its code without calling execve, see for instance some attempts at a user land execve).
  • The first argument passed along the execve system call. By convention, that argument is meant to tell the application its name to let it know how to behave accordingly so is often what is meant by the process name. On Linux, it can be found in /proc/$pid/cmdline, but a process can also change it by modifying the memory pointed to by argv[0].

It should also be noted that there's a lot of variation among the difference Unices.

Related Question