Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I saw this one-liner recently:

$ ps -ef | grep [f]irefox 

thorsen   16730     1  1 Jun19 ?        00:27:27 /usr/lib/firefox/firefox ...

So it seems to return the list of processes with "firefox" in the data but leaving out the grep process itself, and therefore seems roughly equivalent to:

ps -ef |grep -v grep| grep firefox

I can't understand how it works though. I've looked at the man page on grep and elsewhere but haven't found an explanation.

And to compound the mystery if I run:

$ ps -ef | grep firefox  > data
$ grep [f]irefox data

thorsen   15820 28618  0 07:28 pts/1    00:00:00 grep --color=auto firefox
thorsen   16730     1  1 Jun19 ?        00:27:45 /usr/lib/firefox/firefox ....

the [t]rick seems to stop working!

Someone here will know what's going on I'm sure.

Thanks.

share|improve this question
    
Hmm, are you sure that this is correct? ps -eaf|grep [fF]irefox would make more sense. This looks like a regular expression and in means match any one of the enclosed characters. Could be done also as range, e.g. [0-9] –  mbs Jun 20 '12 at 7:17
    
Well yes. That was the problem I was having: a character class containing only one character seemed pointless yet was producing a "mysterious" side effect! Anyway jokerdino has supplied a good explanation. –  Thorsen Jun 20 '12 at 7:31

2 Answers 2

up vote 30 down vote accepted

The square bracket expression is part of the bash shell (and other shells as well) grep's character class pattern matching.

The grep program by default understands POSIX basic regular expressions. With that you can define character classes. For example ps -ef | grep [ab9]irefox would find "airefox", "birefox", "9irefix" if those existed, but not "abirefox".

The command grep [a-zA-Z0-9]irefox would even find all processes that start with exactly one letter or number and end in "irefox".

So ps -ef | grep firefox searches for lines with firefox in it. Since the grep process itself has "firefox" in it, grep finds that as well. By adding a [], we are only searching for the character class "[f]" (which consists of only the letter "f" and is therefor equivalent to just an "f" without the brackets). The advantage of the brackets now is that the string "firefox" no longer appears in the grep command. Hence, grep itself won't show up in the grep result.

Because not very many people are familiar with square brackets as character class matching and regular expressions in general, the second result might look a little mysterious.

If you want to fix the second result, you can use them this way:

ps -ef | grep [f]irefox  > data
grep firefox data

(Reference)

share|improve this answer
1  
Hmm. It didn't occur to me that the [] was something interpreted by the shell BEFORE grep would even get a chance. Thanks for the explanation. All [m]yteries resolved. –  Thorsen Jun 20 '12 at 7:26
    
Happy to help. Have a nice day :) –  jokerdino Jun 20 '12 at 7:29
    
In bash, the square brackets will be passed to grep if there is no match for the word they are in (i.e. no file named "firefox" in the current directory). However, grep also has character classes and [f] in grep is just the same as f. –  Daniel Hershcovich Jun 25 '12 at 18:01
    
Thanks Daniel. ps -ef | grep '[f]irefox' is confirmation I think, since the shell can't be modifying the argument, but the outcome is the same. –  Thorsen Jun 29 '12 at 14:14
6  
Actually in this case I don't think it's interpreted by the shell before grep. I think [f] is the regular expression pattern matching bracket for character classes. As in "[a-z0-9]irefox" grep would match "airefox" and "0irefox" as well. You can easily see that it is not a bash built-in since echo $([f]) returns an error. –  con-f-use Aug 24 '12 at 14:18

The reason is that the string

grep firefox

matches the pattern firefox, but the string

grep [f]irefox

does not match the pattern [f]irefox (which is equivalent to the pattern firefox).

That's why the first grep matches its own process command line, while the second doesn't.

share|improve this answer
    
This makes my head hurt even more –  Pithikos Jul 16 at 14:09

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.