Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why "if $(ps aux | grep ...)" always succeeds in Bash?

Why the following if statement succeeds ?

if $(ps aux | grep -q "bla bla") ; then echo "found" ; fi
like image 997
Misha Moroshko Avatar asked Jan 22 '12 23:01

Misha Moroshko


People also ask

What is ps aux grep?

The ps aux | grep x command gives "better" results than pgrep x essentially because you are missing an option with the latter. Simply use the -f option for pgrep to search the full command line and not only the process name which is its default behavior, eg: pgrep -f php5.

What are $( and $(( )) in bash?

$(...) is an expression that starts a new subshell, whose expansion is the standard output produced by the commands it runs. This is similar to another command/expression pair in bash : ((...)) is an arithmetic statement, while $((...)) is an arithmetic expression. Follow this answer to receive notifications.

What is ps aux in Unix?

The POSIX and UNIX standards require that "ps -aux" print all processes owned by a user named "x", as well as printing all processes that would be selected by the -a option. If the user named "x" does not exist, this ps may interpret the command as "ps aux" instead and print a warning.


2 Answers

Because the grep process itself is being returned by ps. You can "trick" grep to not match itself by surrounding one of the search characters in a character class [ ] which doesn't change the functionality: Just do:

if ps aux | grep -q "[b]la bla" ; then echo "found" ; fi 

Also, the use of process substitution $() is unnecessary. The if will work on the success of the last command in the pipe chain, which is what you want.

Note: The reason the character class trick works is because the ps output still has the character class brackets but when grep is processing the search string, it uses the brackets as syntax rather than a fixed string to match.

like image 144
SiegeX Avatar answered Sep 23 '22 16:09

SiegeX


If you grep the output from ps aux, you will always get a process showing your previous command. To fix this, you can pipe the output to grep twice, once to remove line with "grep" in it, and again for the process your looking for.

ps aux | grep -v "grep" | grep "Finder"
like image 23
Sonic84 Avatar answered Sep 24 '22 16:09

Sonic84