Yesterday Dominis mentioned shell-foo and one cool thing came to my mind what one of my ex colleagues showed me a few years ago. (Hi Pali!)

So let’s pretend you have to locate pid of mysql process. You run the good old ps command, and grep for mysql:

[banyek@sql-master1.bfc ~]$ ps -ef | grep mysql
root      1751     1  0 Jul01 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/sql-master1.bfc.kinja.com.pid
mysql     2424  1751 88 Jul01 ?        21:59:18 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mysql/mysql-error.log --open-files-limit=65535 --pid-file=/var/lib/mysql/sql-master1.bfc.kinja.com.pid --socket=/var/lib/mysql/mysql.sock
banyek    4630  4360  0 11:31 pts/0    00:00:00 grep mysql
[banyek@sql-master1.bfc ~]$

There is one small problem: the grep will find itself too, so if you want count the number of processes it will show one more, or if you only want to find one process with exact pid you have to deal with the plus line in input etc. There is an old fashioned way, to filter the results with an another grep like this:

[banyek@sql-master1.bfc ~]$ ps -ef | grep mysql | grep -v grep
root      1751     1  0 Jul01 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/sql-master1.bfc.kinja.com.pid
mysql     2424  1751 90 Jul01 ?        22:25:20 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mysql/mysql-error.log --open-files-limit=65535 --pid-file=/var/lib/mysql/sql-master1.bfc.kinja.com.pid --socket=/var/lib/mysql/mysql.sock
[banyek@sql-master1.bfc ~]$

It is much better, but have two problems:

The first, the shell will fork a new grep process (ok, this is not a real problem, but …) and the second is you shoot you in your legs if you try to find a grep process on system.

At this point you can use the grep regex match feature, and use it in the process filter like this:

[banyek@sql-master1.bfc ~]$ ps -ef | grep [m]ysql
root      1751     1  0 Jul01 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql --pid-file=/var/lib/mysql/sql-master1.bfc.kinja.com.pid
mysql     2424  1751 90 Jul01 ?        22:34:07 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --user=mysql --log-error=/var/log/mysql/mysql-error.log --open-files-limit=65535 --pid-file=/var/lib/mysql/sql-master1.bfc.kinja.com.pid --socket=/var/lib/mysql/mysql.sock
[banyek@sql-master1.bfc ~]$

What happened? The grep used [m] as a regex character which only matches letter ‘m’ – so the output is the same as before, but the ‘[m]ysql’ didn’t matched ‘mysql’, so it was clearly filtered out.

Cool, huh?