Operating System - HP-UX
1834162 Members
2820 Online
110064 Solutions
New Discussion

Re: scripting problem for repeat lines

 
SOLVED
Go to solution
Ratzie
Super Advisor

scripting problem for repeat lines

I am having some problems trying to create a script.
This is what I have it doing... in big picture...
I have a file of 14 ip's that I have an expect script uses to telent and change passwd.

The only way I can make sure that all of them are accessed is, on login I "put" a comment in a file $IP, logged in.

Then if it actually makes its way and changes the passwd, it puts another line $IP, changed passwd.

Now at the end the whole file should be wc -l =30. If not it emails the file.
What I would like it to do is send me the IP that did not sucessfully do a logged in, and I passwd change.

This is a snipit of the file...

**** LOGIN ENTRIES for Wed Feb 4 10:25:03 CST 2004 ****

xxx.xxx.xxx.20, logged in.
xxx.xxx.xxx.20, changed passwd.
xxx.xxx.xxx.21, logged in.
xxx.xxx.xxx.21, changed passwd.
xxx.xxx.xxx.22, logged in.
xxx.xxx.xxx.22, changed passwd.
xxx.xxx.xxx.23, logged in.
xxx.xxx.xxx.24, logged in.
xxx.xxx.xxx.24, changed passwd.

So as you can see, I had an error with xxx.xxx.xxx.23
How can I just parse that out, and send in am email, instead of the whole file and I have to search for it...
14 REPLIES 14
Mark Greene_1
Honored Contributor

Re: scripting problem for repeat lines

Will your script accomodate adding a comment if the login or password change were unsuccessfull? Then you could just grep for those messages instead.

mark
the future will be a lot like now, only later
Sridhar Bhaskarla
Honored Contributor
Solution

Re: scripting problem for repeat lines

Hi,

A simple script would be to get the list of the IP addresses and grep for "changed passwd" for that IP address. If it returns 1, then the script failed for that IP. For ex.,

#!/usr/bin/ksh
EMAIL=yourid@yourdomain.com
STAMP=0

trap 'rm -f /tmp/host$$' 0 1 2
for HOST in $(awk '{FS=",";print $1}' data1 |sort|uniq)
do
grep $HOST data1 |grep -q "changed passwd"
if [ $? != 0 ]
then
echo $HOST >> /tmp/host$$
STAMP=1
fi
done


Modify EMAIL in the script to point to yours.

-Sri

if [ $STAMP = 1 ]
then
mailx -s "List of failed hosts" $EMAIL < /tmp/host$$
fi
You may be disappointed if you fail, but you are doomed if you don't try
Ratzie
Super Advisor

Re: scripting problem for repeat lines

Why does this not work...

rm -r /tmp/host.not
for HOST in $(awk '{print $1}' /tmp/host |sort|uniq)
do
grep $HOST /tmp/host |grep -q "changed passwd"
if [ $?!=1 ]
then
echo $HOST >>/tmp/host.not
fi
done


It still puts every line in host.not
I have taken out the comma to awk the file better.
Sridhar Bhaskarla
Honored Contributor

Re: scripting problem for repeat lines

Hi,

Based on your input file as given in the example, the seperator is , so you will need to use 'awk '{FS=",";print $1}'' to get the IP addresses.

-Sri
You may be disappointed if you fail, but you are doomed if you don't try
Sridhar Bhaskarla
Honored Contributor

Re: scripting problem for repeat lines

Gotcha what you meant.

You are right. You don't need to use FS=",".

The problem is grep -q "chaged password" will return 0 if it is found. So, the test would be

if [ $? != 0 ] # <====
then
echo $HOST >>/tmp/host.not
fi

as per your script.

-Sri
You may be disappointed if you fail, but you are doomed if you don't try
Ratzie
Super Advisor

Re: scripting problem for repeat lines

Well, that confuses me, because if it does not find "changed passwd" it will return 1

And that is what I want entered into the host.not file.

I want all the IP addresses that do not have "changed passwd" in the host.not file.
Sridhar Bhaskarla
Honored Contributor

Re: scripting problem for repeat lines

Let me try -

1. I used FS="," otherwise you will get hostnames with a ',' with them. So, your output will look better.

2. To clarify the last post -

grep xxx.xxx.xxx.24 myhost|grep -q "changed passwd"

This will return 0 ($? variable)

grep xxx.xxx.xxx.23 myhost |grep -q "changed passwd"

This will return 1 ($? variable)

You can do it in multiple ways


if [ $? != 1 ]

This means "changed passwd" string may be associated with the host. This is what you had not what you want.

if [ $? = 1 ]

This will work for this situation. However, there is no guarantee that $? is always going to be 1 for failures.

if [ $? != 0 ]

This means unsuccessful. This means "changed passwd" string is not associated with the host. This is what you want.

Try it and see.

-Sri
You may be disappointed if you fail, but you are doomed if you don't try
Ratzie
Super Advisor

Re: scripting problem for repeat lines

Yes, I have been able to test, the same as you from command line.
but, it still errors at at...
if [ $?=1 ]
then
echo $HOST >>/tmp/host.not
fi

I still get the same answer if I do...
if [ $?!=0 ]

The exact same. I must be doing something wrong.
I modified the host file and took out all the comma's so now it is just XXX.XXX.XXX.21 logged in
and so on..



rm -r /tmp/host.not
for HOST in $(awk '{print $1}' /tmp/host |sort|uniq)
do
grep $HOST /tmp/host |grep -q "changed passwd"
if [ $?=1 ]
then
echo $HOST >>/tmp/host.not
fi
done

I appreciate your help!
Laura


Sridhar Bhaskarla
Honored Contributor

Re: scripting problem for repeat lines

I don't know if it is a copy-paste error or you really have it in your script

$?=1 make sure there are spaces between $? and 1

[ $? = 1 ]

-Sri
You may be disappointed if you fail, but you are doomed if you don't try
Seth Parker
Trusted Contributor

Re: scripting problem for repeat lines

This looked like too much fun to pass up. (I'm such a dork!) Try this:

grep -Fv "$(grep -v logged test.txt | cut -f1 -d,)" test.txt

It assumes your results are in test.txt.

This returns "xxx.xxx.xxx.23, logged in."

If you just want the IP address, tack on another " | cut -f1 -d," at the end and you'll get "xxx.xxx.xxx.23"

Regards,
Seth
Seth Parker
Trusted Contributor

Re: scripting problem for repeat lines

I was a little tired when I posted last night. Here's another version that's a little more readable:

grep -Fv "$(grep changed test.txt | cut -f1 -d,)" test.txt

Regards,
Seth
Mike Stroyan
Honored Contributor

Re: scripting problem for repeat lines

Removing the comma from the grep pattern leads to trouble from matching patterns that are substrings of the real IP. As an example, if the input file included a line that succeeded on xxx.xxx.xxx.2, then a simple grep based script would fail to catch a failure on xxx.xxx.xxx.23 or any other xxx.xxx.xxx.2* address. There is a similar risk of subsets at the front of the pattern, although those are less common in actual IP addresses.

xxx.xxx.xxx.2, logged in.
xxx.xxx.xxx.2, changed passwd.
xxx.xxx.xxx.20, logged in.
xxx.xxx.xxx.20, changed passwd.
xxx.xxx.xxx.21, logged in.
xxx.xxx.xxx.21, changed passwd.
xxx.xxx.xxx.22, logged in.
xxx.xxx.xxx.22, changed passwd.
xxx.xxx.xxx.23, logged in.
xxx.xxx.xxx.24, logged in.
xxx.xxx.xxx.24, changed passwd.

Here is an awk one-liner that uses exact comparisons. It won't have the subset pattern problem.

awk -F, '/logged in/{l[$1]=1}/changed/{delete l[$1]}END{for(i in l){print i}}' test.txt
Sridhar Bhaskarla
Honored Contributor

Re: scripting problem for repeat lines

Hi,

Mike is absolutely correct. My stupid brain didn't think beyond your example. I guess you already thought of it by using the , in your script.

-Sri
You may be disappointed if you fail, but you are doomed if you don't try
Seth Parker
Trusted Contributor

Re: scripting problem for repeat lines

Excellent point, Mike!

The only way my command will work properly is if there is a comma in the file and it's part of the search. So, the command would be:

grep -Fv "$(grep changed test.txt | cut -f1 -d' ')" test.txt

That way the comma is part of the search as well, so "xxx.xxx.xxx.2," won't match "xxx.xxx.xxx.222,", etc.

Thanks for pointing that out, Mike. Hehe, I guess I was too happy with myself to notice that being a problem.

Regards,
Seth