How to avoid arguments inside Nawk command?

Hi,

Here is my command

print $2

was meant to select the second column however, it is getting substituted with the second argument that was passed to the script.

Can you please tell me how can I resolve this ?

How do you know that the second argument of the script is not the same as the second column returned by ps?

What is the value of $2 (the argument to the script) and what is the output of the ps command?

My script terminates before I expect it to ... The for loop break in between for some reason.

Here is my script run.sh

#!/bin/bash
 echo "Stopping Servers"
 for i in $(echo $1 | sed "s/,/ /g")
do
echo "/usr/ucb/ps auxwww | grep $i | grep $2 | grep -v grep | nawk 'NR==1{print $2}'"
mypid=`/usr/ucb/ps auxwww | grep $i | grep $2 | grep -v grep | nawk 'NR==1{print $2}'`
 echo "MYPID is:$mypid"
kill -9 $mypid
done
 echo "Clearing Cache..."

Here is the INCORRECT output:

bash-3.2$ bash -x /web/run.sh MS01,MS02,MS03,MS04 mydomain01
+ echo 'Stopping Servers'
Stopping Servers
++ echo MS01,MS02,MS03,MS04
++ sed 's/,/ /g'
+ for i in '$(echo $1 | sed "s/,/ /g")'
+ echo '/usr/ucb/ps auxwww | grep MS01 | grep mydomain01 | grep -v grep | nawk '\''NR==1{print mydomain01}'\'''
/usr/ucb/ps auxwww | grep MS01 | grep mydomain01 | grep -v grep | nawk 'NR==1{print mydomain01}'
++ /usr/ucb/ps auxwww
++ grep MS01
++ grep mydomain01
++ grep -v grep
++ nawk 'NR==1{print $2}'
+ mypid=6433
+ echo 'MYPID is:6433'
MYPID is:6433
+ kill -9 6433
+ for i in '$(echo $1 | sed "s/,/ /g")'
+ echo '/usr/ucb/ps auxwww | grep MS02 | grep mydomain01 | grep -v grep | nawk '\''NR==1{print mydomain01}'\'''
/usr/ucb/ps auxwww | grep MS02 | grep mydomain01 | grep -v grep | nawk 'NR==1{print mydomain01}'
++ /usr/ucb/ps auxwww
++ grep MS02
++ grep mydomain01
++ grep -v grep
++ nawk 'NR==1{print $2}'
+ mypid=5370
+ echo 'MYPID is:5370'
MYPID is:5370
+ kill -9 5370
Killed
 bash-3.2$

Can you please suggest what's wrong with my script ? Why MS03 and MS04 is not executed by the for loop ?

Well, it looks like the ps is picking up the process ID ($$) of your script when it gets to 'M02' (whatever that it), and killing it.

Perhaps you could add "| grep -v $$" to your command, to exclude your script from the results, although this approach isn't good at all. It would be better to use positional fields from the output, as grep will pick up any old thing it finds, regardless of where it is in the output, unless it's very finely tuned.

1 Like

... because the two greps are so unprecise that they match the own bash process

bash -x /web/run.sh MS01,MS02,MS03,MS04 mydomain01

The echo output differs because its arguments are in "quotes".
echo "print '$var'" expands differently because the ' are within "quotes" and have no special meaning.
In contrast to echo print '$var' where the ' are active quotes and protect the $var from expansion.

Maybe you can give an example how the processes look that are to be killed?

This line:

Won't work - at least not in the way you perhaps supposed it to work: the shell maintains one (only one!) flag of sorts for being inside or outside of a quotation. That means quotes cannot be nested and this:

"some-string 'foo bar' other string"

is NOT a single-quoted string inside a double-quoted string but in fact a double-quoted string with just a few single-quote-characters in it. In other words: the single-quotes lose their special meaning inside double-quotes.

This is why "...$2...." and "...'$2'..." are basically the same.

I hope this helps.

bakunin

grep -v $$ helped !!. Thank you.