When faced with the task of finding something in "ps", old Unix hands will almost automatically type "ps -e | grep" and follow that with whatever they are looking for. I can tell you that after so many years of doing that, it's almost reflexive. We may know that there are other ways, but it's the old saying: walk too close to a habit and it will bite you.
The good thing is that most of the time that habit just wags its tail and gives us what we want. Even when there is a playful little snap of the teeth accompanying the tail wagging, we're often doing that at the command line and can ignore any superfluous output. It's when our grepping is buried in a script that the results may turn tragic.
There are a LOT of things that can go wrong with "ps -e | grep". I'll try to cover the most damaging things, but I might miss one or two. If you take away nothing else from what follows, make it this: test scripts carefully and do not assume anything!
There are other ways to get processes matching some string. For example, on Linux:
# ps -C watcher PID TTY TIME CMD 9153 ? 00:00:00 watcher # ps -C sshd PID TTY TIME CMD 2246 ? 00:00:01 sshd 5435 ? 00:00:00 sshd 5577 ? 00:00:00 sshd # pgrep -l sshd 2246 sshd 5435 sshd 5577 sshd
But "-C" is different on Mac OS X:
ps -C sshd
ps: illegal argument: sshd
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
[-g grp[,grp...]] [-u [uid,uid...]]
[-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
ps [-L]
OS X ps has a -C flag, but it isn't for showing processes. The "pgrep" will work, though.
OS X has another little gotcha.
$ ps -e |grep taskgated 1403 ?? 0:00.01 /usr/libexec/taskgated -s 1432 ttys001 0:00.00 grep taskgated
Most non-BSD Unix folk would have expected one line, not two. To get that from OS X, add -c:
$ ps -ec |grep taskgated 1403 ?? 0:00.01 taskgated
There are other ways to get rid of unwanted lines. Section 3.10 of Unix - Frequently Asked Questions suggests
ps ux | awk '/name/ && !/awk/ {print $2}'
and you might see this:
ps aux | grep something | grep -v grep
This is a clever way (though harder to type):
ps aux | grep [s]shd
In case you don't see why it's because the "grep" line will contain "grep [s]shd" (with the brackets) which won't match what grep is looking for.
But in all cases, watch your switches. On Linux, for example:
# ps a PID TTY STAT TIME COMMAND 2833 hvc0 Ss+ 0:00 /sbin/getty -8 38400 hvc0 3257 pts/1 Ss 0:00 /bin/bash 3271 pts/1 S 0:00 sudo su - 3274 pts/1 S 0:00 su - 3275 pts/1 S 0:03 -su 5578 pts/0 Ss 0:00 -bash 5584 pts/0 S+ 0:00 screen -D -r 12201 pts/1 R+ 0:00 ps a # ps -a PID TTY TIME CMD 3271 pts/1 00:00:00 sudo 3274 pts/1 00:00:00 su 3275 pts/1 00:00:03 bash 5584 pts/0 00:00:00 screen 12202 pts/1 00:00:00 ps
Those would be identical on OS X!
Before we get too deep into ps idiosyncrasies here, you may want to take a look at I_WANT_A_BROKEN_PS and How "ps" works and why.
Let's move on to look at a scripting problem:
#!/bin/bash X=`ps -e | grep $1` # -ec on Mac echo $X
Nothing wrong with that, right? Look, it works:
$ ./t.sh vim 1474 ttys001 0:00.00 /bin/bash ./t.sh vim 1475 ttys001 0:00.00 /bin/bash ./t.sh vim 1477 ttys001 0:00.00 grep vim 1462 ttys002 0:00.01 vim foops
OK, what about this?
$ ./t.sh taskgated 1480 aa ab bh dl ds dt ex me pj pt re sc t1 t2 tp tt xt zz 0:00.01 taskgated
What's all that "aa ab bh" stuff? Here, let's see if this helps:
$ ls ?? aa bh ds ex pj re t1 tp xt ab dl dt me pt sc t2 tt zz
You have to be careful with pulling in the output of "ps" and randomly echoing it. The "ps" lines for daemons will include a "?" in the controlling tty column, so if you did "x=`ps -e | grep whatever`", the returning line would have a "?" (on Mac OS X, two "??"). If your script then does "echo $x", the ? mark or marks will match one or two character file names that happen to be present in your current directory. As this is directory dependent, your script might appear to work correctly initially and then break later.
You can get unexpected results with "pgrep" too.
Another thing that can bite you is the width of the listing. What you see with "ps" at command line is not necessarily what "grep" sees.
$ ps -e # partial output ... 1589 ?? 0:00.01 /System/Library/Frameworks/CFNetwork.framework/Version 1629 ?? 0:00.23 /System/Library/CoreServices/System Events.app/Content 1644 ?? 0:00.39 /System/Library/Frameworks/CoreServices.framework/Fram ... $ ps -e | grep . ... 1589 ?? 0:00.01 /System/Library/Frameworks/CFNetwork.framework/Versions/A/Support/cookied 1629 ?? 0:00.23 /System/Library/CoreServices/System Events.app/Contents/MacOS/System Events -psn_0_1069317 1644 ?? 0:00.48 /System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/ Versions/A/Support/mdworker -s mdworker -c MDSImporterWorker -m com.apple.mdworker.shared ...
Without more instructions, "ps -e" stops at your terminal width. When it is piped, it does not. That could lead to more matches than you expected.
More Articles by Anthony Lawrence - Find me on Google+ 2013-08-16
Have you tried Searching this site?
Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates
This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more. We appreciate comments and article submissions.
Many of the products and books I review are things I purchased for my own use. Some were given to me specifically for the purpose of reviewing them. I resell or can earn commissions from the sale of some of these items. Links within these pages may be affiliate links that pay me for referring you to them. That's mostly insignificant amounts of money; whenever it is not I have made my relationship plain. I also may own stock in companies mentioned here. If you have any question, please do feel free to contact me.
I am a Kerio reseller. Articles here related to Kerio products reflect my honest opinion, but I do have an obvious interest in selling those products also.
Specific links that take you to pages that allow you to purchase the item I reviewed are very likely to pay me a commission. Many of the books I review were given to me by the publishers specifically for the purpose of writing a review. These gifts and referral fees do not affect my opinions; I often give bad reviews anyway.
We use Google third-party advertising companies to serve ads when you visit our website. These companies may use information (not including your name, address, email address, or telephone number) about your visits to this and other websites in order to provide advertisements about goods and services of interest to you. If you would like more information about this practice and to know your choices about not having this information used by these companies, click here.
Click here to add your comments - no registration needed!
Don't miss responses! Subscribe to Comments by RSS or by Email
Click here to add your comments
If you want a picture to show with your comment, go get a Gravatar