sat
sat

Reputation: 14949

How the grep '[p]rocessname' ignores the 'grep' process in 'ps -ef'?

When I am trying to find out the specific process by using ps -ef | grep 'processname', it is giving grep process also.

Like this:

$ ps -ef | grep 'sleep'
root     25309 16242  0 18:08 pts/17   00:00:00 sleep 300
root     25316  6114  0 18:08 pts/2    00:00:00 grep --color=always sleep

For that, I usually use ps -ef | grep '[p]rocessname' and this has been suggested by many websites and links in SO. Now, I am getting expected output.

$ ps -ef | grep '[s]leep'
root     25309 16242  0 18:08 pts/17   00:00:00 sleep 300

My question is,

How the grep '[p]rocessname' ignores the grep process?

Because, When I redirect the output to some file and doing the grep. But, This time it gives me two line. I get confused. Here, What I have tried.

$ ps -ef | grep 'sleep' > input.txt

$ grep 'sleep' input.txt 
root     25309 16242  0 18:08 pts/17   00:00:00 sleep 300
root     25689  6114  0 18:11 pts/2    00:00:00 grep --color=always sleep

$ grep '[s]leep' input.txt 
root     25309 16242  0 18:08 pts/17   00:00:00 sleep 300
root     25689  6114  0 18:11 pts/2    00:00:00 grep --color=always sleep

$ cat input.txt  | grep '[s]leep'
root     25309 16242  0 18:08 pts/17   00:00:00 sleep 300
root     25689  6114  0 18:11 pts/2    00:00:00 grep --color=always sleep

What is the difference between ps -ef | grep '...' and grep '...' file ?

Upvotes: 1

Views: 640

Answers (2)

Kent
Kent

Reputation: 195049

it is an easy trick.

say you have only two java processes running on your machine, no other processes. with your ps -ef|grep java you have 3 processes

java ...
java ...
grep java

and your grep gives you 3 output lines. because three lines match regex: java

but if you do it with grep '[j]ava', you have these 3 processes:

java...
java...
grep [j]ava

The last line won't match regex [j]ava, it matches \[j\]ava, that's why your grep '[j]ava' filtered the last process out, thus only 2 output lines

Upvotes: 3

Srini V
Srini V

Reputation: 11355

When you try to do a normal search on all you see all process including your grep with the search pattern

$ ps -ef | grep 'sleep'
root     25309 16242  0 18:08 pts/17   00:00:00 sleep 300
root     25316  6114  0 18:08 pts/2    00:00:00 grep --color=always sleep

When you use ps -ef | grep '[p]rocessname' , you will be getting the expected output.

$ ps -ef | grep '[s]leep'
root     25309 16242  0 18:08 pts/17   00:00:00 sleep 300

Using that regex you are launching a process which its ps string will not match itself, since the regexp matches "sleep" and not "[s]leep". That way you'll exclude the process that has the string "[s]leep" which in this case is grep; The same can be applied to pgrep, egrep, awk, sed, etc... whichever command you used to define the regex.

From man 7 regex

A bracket expression is a list of characters enclosed in "[]". It normally matches any single character from the list (but see below).
If the list begins with '^', it matches any single character (but see below) not from the rest of the list. If two characters in the list are separated by '-', this is shorthand for the full range of characters between those two (inclusive) in the collating sequence, for example, "[0-9]" in ASCII matches any decimal digit. It is illegal(!) for two ranges to share an endpoint, for example, "a-c-e".

Upvotes: 0

Related Questions