2009-12-04

awk over non-interactive ssh sessions

I had trouble wrapping my brain around this one today. I was attempting to grab the second field of ps(1) output to display only the PID of a given process. Of course, if we had pgrep and pkill, this would be a no-brainer. But we don't.

Note, when I use grep on ps(1) I also pipe it through grep -v grep (which ignores any line containing the pattern "grep") so that grepping for some_process doesn't end up like this:

root 751 200 0 Jun 25 ? 3:11 /usr/sbin/some_process -d
axon 2429 222 0 4:54:59 pts/1 0:00 grep some_process

First attempt:

ssh somebox "ps -ef | grep some_process | grep -v grep | awk '{print $2}' "
The output, though, was the whole line out of ps.

root 751 200 0 Jun 25 ? 3:11 /usr/sbin/some_process -d

I attempted escaping the ticks, double ticks, escaped double ticks, double quotes, and all kinds of madness. Nothing was working. I was getting either a whole ps line (as if awk wasn't even there) or syntax errors from awk.

Finally, I ask a co-worker (the biggest shell geek I know) pointed out that it was being frobbed by two separate shells. He gave me a somewhat complicated line to use, but I figured out an easier way. The second shell was interpreting $2, thinking I was referencing a shell argument, and was passing nothing to awk. Solution? Escape $2.

ssh somebox "ps -ef | grep some_process | grep -v grep | awk '{print \$2}' "
751

Hooray! Hopefully this helps some poor sysadmin somewhere when the time comes to reference variables remotely in something like perl or awk.

blog comments powered by Disqus