1

I'm not a software/scripting folk myself so struggling to understand what is happening here:

watch -n 0.2 'ps -p $(pgrep -d',' -x snmpd) -o rss= | awk '{ i += $1 } END { print i }''

Basically I am wanting to print the Resident Set Size value of my snmp daemon 5 times a second (for fair resolution). I then intend on building from this to redirect the output to a text file for later analysis where I can put the data into a graph for instance.

The trouble I have here is that I can run the following fine:

watch -n 0.2 'ps -p $(pgrep -d',' -x snmpd) -o rss'

However I require just the numeric value only so using awk to strip out everything but that value is important.

Running the first command above returns an error and I suspect due to the way watch is handling the single quotes, but I'm not smart enough to understand it....

Any suggestions?

Also, I have read that

pmap -x [pid]

works too, however when I run it with snmpd's respective PID the output is zero when clearly it is not. Any ideas on this too?

Regards.

uncle-junky
  • 723
  • 1
  • 8
  • 33

1 Answers1

1

If the quoted command is accurate:

watch -n 0.2 'ps -p $(pgrep -d',' -x snmpd) -o rss= | awk '{ i += $1 } END { print i }''
             ^                ^ ^                         ^                           ^^
             1                0 1                         0                           10

You've got problems with your single quotes. The 1 indicates 'start of quote', the 0 indicates end of quote. The following command line should work for you:

watch -n 0.2 'ps -p $(pgrep -d"," -x snmpd) -o rss= | awk "{ i += $1 } END { print i }"'
             ^                                                                         ^
             1                                                                         0

The double quotes and $(...) also work correctly. The single-quoted string is sent to watch as a whole. Previously, you had multiple arguments.

Note that in your working command, you have:

watch -n 0.2 'ps -p $(pgrep -d',' -x snmpd) -o rss'
             ^                ^ ^                 ^
             1                0 1                 0

Now, because the character between the middle '01' is a comma, not a blank, the shell continues to give watch a single argument, but it doesn't contain the quotes. What watch gets as its third argument is:

ps -p $(pgrep -d, -xsnmpd) -o rss

With your awk-line, 1watch` gets multiple arguments:

ps -p $(pgrep -d, -x snmpd) -o rss= | awk {
i
+=
$1
}
END
{
print
i
}

And it doesn't know what to do with the excess. (NB: The value of $1 would be the shell's current $1 (possibly an empty string, in which case the argument corresponding to $1 would be omitted.)


This variant, with a backslash before the $1 in the awk script, seemed to work for me (when I looked for a program which actually was running — snmpd was not running on the machine where I tested, and things fell apart because of that):

sh -c 'ps -p $(pgrep -d"," -x snmpd) -o rss= | awk "{ i += \$1 } END { print i }"'

If you think there's any danger that there is no snmpd process, then you need to do things a little less compactly. That's the command I tested; you can put the watch -n 0.2 in place of the sh -c. But note that the man page for watch does explicitly say:

Note that command is given to "sh -c" which means that you may need to use extra quoting to get the desired effect.

That was very accurate!

If you prefer to stick with single quotes, you could try:

watch -n 0.2 'ps -p $(pgrep -d"," -x snmpd) -o rss= | awk '\''{ i += $1 } END { print i }'\'

The idea behind the '\'' motif is that the first single quote terminates the current single-quoted string; the backslash single quote adds an actual single quote, and the last single quote starts a new single-quoted string. The '\' at the end could also be written '\''', but the last two single quotes are redundant, so I left them out.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks for your effort JL. I like the explanation and suggestion of the double quotes which makes sense. *awk* however doesn't like the use of the double quotes though... I'm lost on this one. – uncle-junky Mar 30 '13 at 01:01
  • I'm tolerably sure that the diagnosis of what went wrong is on target. It is harder to be sure about the replacement. You're saying it doesn't work. But the `$(pgrep...)` stuff worked OK. The man page for [`watch`](http://linux.about.com/library/cmd/blcmdl1_watch.htm) says: _Note that_ command _is given to "sh -c" which means that you may need to use extra quoting to get the desired effect._ – Jonathan Leffler Mar 30 '13 at 03:04
  • OK. Without giving the command to *watch*, *awk* does not like the use of the double quotes. So when passed to watch *awk* is still producing the error. That said, your single quote variant works fine. Many thanks. – uncle-junky Mar 30 '13 at 13:30