40

Is there any way to get pgrep to give me all the info about each process that ps does? I know I can pipe ps through grep but that's a lot of typing and it also gives me the grep process itself which I don't want.

chicks
  • 3,639
  • 10
  • 26
  • 36
JoelFan
  • 2,165
  • 5
  • 24
  • 30

9 Answers9

29

pgrep's output options are pretty limited. You will almost certainly need to send it back through ps to get the important information out. You could automate this by using a bash function in your ~/.bashrc.

function ppgrep() { pgrep "$@" | xargs --no-run-if-empty ps fp; }

Then call the command with.

ppgrep <pattern>
Dan Carley
  • 25,189
  • 5
  • 52
  • 70
  • 3
    Thanks! I modified it to: `function ppgrep() { pgrep "$@" | xargs ps fp 2> /dev/null; }` Otherwise, if no processes match your search, it dumps a whole `ps` usage megilla. – JoelFan Dec 10 '10 at 04:17
  • On OS X, the `ps` needs a hyphen for the flags: `function ppgrep() { pgrep "$@" | xargs ps -fp 2> /dev/null; }` – Erik Nomitch Sep 29 '15 at 11:34
  • 2
    If you want to avoid the ps usage page, GNU xargs has an option, `-r` that will only execute the command if it has received a list. – Doug Apr 22 '16 at 03:19
  • 2
    More concise way is `ps fp $(pgrep -d, "$@")` – Igor Mikushkin Apr 12 '19 at 15:09
19

Combine pgrep with ps using xargs!

pgrep <your pgrep-criteria> | xargs ps <your ps options> -p

For example try

pgrep -u user | xargs ps -f -p

to get a full process list of user. Option -u user limits pgrep to the user given (as a number or name) while the ps options -f -p request a full format listing for the selected PID.

It's nice that you keep the first line with the column names. grep always drops the column names.

nalply
  • 1,067
  • 1
  • 10
  • 19
  • excellent! this resolves a strange problem with arcgis server startup script for xfvb – prusswan Jul 17 '14 at 11:25
  • 2
    This should be the accepted answer, because it uses unix pipes in a proper way, taking a list of PIDs from one tool and feeding back into another (if it seems like hackery, it's not - this technique can be used in LOTS of UNIX tools, like email grep tools. The Bash function ppgrep() is an unnecessary dependency, and avoids confronting the learning opportunity presented here.) – Scott Prive Jul 24 '17 at 16:33
16

The following only gives you PID + full command-line. For "all the info ps does", see other answers...

Most linuxes use procps-ng. Since 3.3.4 (released in 2012), pgrep -a (--list-full) shows the full command line.
Note: By default pgrep only matches the pattern you give against the executable name. If you want to match against the full command line (as grepping ps does), add the -f (--full) option.

In older versions (including the original procps project), -l option showed info but it's behavior varied:

  • pgrep -fl matched the pattern against full command line and showed the full command line.
  • pgrep -l alone matched only executable name and showed only executable name.
    If you don't want full match, you couldn't see the full command line :-( [https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=526355#15]

Not sure what code *BSD use but their man page documents the old -fl behavior.

Unfortunately you can't even use -fl portably - in recent procps-ng, -f (--list-name) always prints only the executable name.

11

Linux grep

For the GNU version of pgrep long + fuzzy output is achieved with -af and the string must be case-sensitive (i.e. there is no option for case-insensitivity).

$ pgrep -af apache

OUTPUT:
    1748 /usr/sbin/apache2 -k start

Man page:

   -a, --list-full
       List  the  full  command line as well as the process ID.  (pgrep only.)

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

MacOS/BSD grep

On MacOS/BSD -l (long output) in combination with -f (match against full argument lists) will display the complete command (-i adds case-insensitivity):

$ pgrep -fil ssh

OUTPUT:
    33770 ssh: abc@192.168.0.123-22 [mux] t

man page:

 -l          Long output.  For pgrep, print the
             process name in addition to the
             process ID for each matching
             process.  If used in conjunction
             with -f, print the process ID and
             the full argument list for each
             matching process.  For pkill, dis-
             play the kill command used for
             each process killed.

❗️NOTE: GNU grep can be installed on MacOS with brew install pgrep — this will expose the GNU flavour under /usr/local/bin/pgrep and depending on your $PATH config might break code which relies on the BSD syntax of pgrep.

ccpizza
  • 226
  • 2
  • 5
2

Use the -v option to grep - it returns everything BUT the requested pattern.

ps -ef | grep <process> | grep -v grep
baumgart
  • 2,423
  • 18
  • 17
1

I know it is an old topic. However, It was useful to me, and I would like to share what I did that worked. It is pretty straightforward for beginner (like me) and may help others:

[root@2a8ad900f55e tmp]# pgrep -f '(^|/)db2fmcd'|xargs ps |awk '{print $5}'
COMMAND
/opt/ibm/db2/V11.5/bin/db2fmcd

Note that the column "CMD" was also showed, but the question of this thread was to show the command, and not only the command. Anyway, I am trying to remove that column and will update my post with the command too.

Note: The arguments "--no-headers and -o command" isolated the output only to the command. And I could remove the awk print.


[root@2a8ad900f55e tmp]# pgrep -f '(^|/)db2fmcd'|xargs ps -o command --no-headers
/opt/ibm/db2/V11.5/bin/db2fmcd
[root@2a8ad900f55e tmp]#
Pierre.Vriens
  • 1,159
  • 34
  • 15
  • 19
haxkkroto
  • 11
  • 2
0

I don't think there is, the most information you can get is the name and process id by using the -l option to pgrep.

ps supports all sorts of formatting options, so I would just make an alias for what you want to save the typing. A simple way to exclude the grep process from the output us to include an additional pipe to grep -v grep to exclude any grep processes.

Kyle Brandt
  • 82,107
  • 71
  • 302
  • 444
0

In order to eliminate the grep process, you can use brackets as part of your pattern:

ps -ef | grep '[t]ty'

You can do this with ps and pgrep:

ps -fp $(pgrep -d, tty)
Dennis Williamson
  • 60,515
  • 14
  • 113
  • 148
-1

This will help you I guess:

ps auxww