问题
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.
回答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.
来源:https://stackoverflow.com/questions/15713344/what-is-wrong-with-this-command