1752794 Members
6917 Online
108789 Solutions
New Discussion юеВ

Looping in a script

 
SOLVED
Go to solution
Jeeshan
Honored Contributor

Looping in a script

I have a script which is ran to get a file from ftp site and manipulate it. but the file is overwritten and match with the pattern. if pattern found then do some jobs. here is that
#!/usr/bin/sh
function ftps {
sleep 20
USER=anonymous
PW=xxxxx
ftp -v -i -n << EOF
user $USER $PW
ascii
mget notification.log
bye
EOF
}
ftps
MAIL_RECEIVER=""
a=`cat notification.log |head -n 5|sed 's/^.............................................//' > file.not.tmp`
b=`cat file.not.tmp |awk '{print $4}'`
if [[ $b = "" ]]
then
mailx -s "CDR backup is completed in blbilstg server" $MAIL_RECEIVER < file.not.tmp
fi

The scripts seems ok if the pattern is matched. But my concern is, I want to run the script until the pattern is not matched.
a warrior never quits
11 REPLIES 11
Doug O'Leary
Honored Contributor

Re: Looping in a script

Hey;

If I'm understanding you correctly, you should be able to change the if statement at the end to

while [ "${b}" = "" ]
do
...

done

I'd caution against this implemenetation, though. You're setting yourself up for problems if the file gets overwritten while it's being processed, if the ftp fails for any reason, etc.

HTH;

Doug O'Leary

------
Senior UNIX Admin
O'Leary Computers Inc
linkedin: http://www.linkedin.com/dkoleary
Resume: http://www.olearycomputers.com/resume.html
James R. Ferguson
Acclaimed Contributor
Solution

Re: Looping in a script

Hi Ahsan:

There are several ways to do this. One way is to use a 'true' loop and 'break' out of it when the condition you want to see is satisfied:

#!/usr/bin/sh
function ftps {
sleep 20
USER=anonymous
PW=xxxxx
ftp -v -i -n server_name << EOF
user $USER $PW
ascii
mget notification.log
bye
EOF
}
ftps
MAIL_RECEIVER=""
a=`cat notification.log |head -n 5|sed 's/^.............................................//' > file.not.tmp`
while true
do
b=`cat file.not.tmp |awk '{print $4}'`
if [[ $b = "" ]]
then
mailx -s "CDR backup is completed in blbilstg server" $MAIL_RECEIVER < file.not.tmp
break
fi
done

...Now, let's make some improvements to your general script. (1) Eliminate useless 'cat' processes! (2) the 'sed' match can be made much more readable with a repeat part; (3) eliminate the backticks and use the clearer POSIX shell $() notation for command execution:

#!/usr/bin/sh
function ftps {
sleep 20
USER=anonymous
PW=xxxxx
ftp -v -i -n server_name << EOF
user $USER $PW
ascii
mget notification.log
bye
EOF
}
ftps
MAIL_RECEIVER=""
a=$(cat notification.log |head -n 5|sed 's/^.{45}//' > file.not.tmp)
while true
do
b=$(awk '{print $4}' file.not.tmp)
if [[ $b = "" ]]
then
mailx -s "CDR backup is completed in blbilstg server" $MAIL_RECEIVER < file.not.tmp
break
fi
done

Regards!

...JRF...
Jeeshan
Honored Contributor

Re: Looping in a script

thanks for your inputs.

My concern is notification.log is overwritten and i do want to do ftp again until the pattern is matched.
a warrior never quits
James R. Ferguson
Acclaimed Contributor

Re: Looping in a script

Hi (again) Ahsan:

> My concern is notification.log is overwritten and i do want to do ftp again until the pattern is matched.

Since you are getting (with FTP) and then parsing this file, I would remove the file before performing the FTP. This also serves as a success-or-failure test:

...
rm -f notification.log
ftps
...

By the way, since you reference this file name multiple times, you should consider making it the value of a variable:

MYLOG=notification.log
...
rm -r ${MYLOG}
ftps
...

Too, I fail to see why you are using 'mget' instead of a simple 'get'. You aren't globbing for multiple files.

Regards!

...JRF...
Jeeshan
Honored Contributor

Re: Looping in a script

Yeah JRF, you are right, I should not suppose to mget instead of get.

BTW, where i can put this rm then ftps lines?
a warrior never quits
James R. Ferguson
Acclaimed Contributor

Re: Looping in a script

Hi (again) Ahsan:

> BTW, where i can put this rm then ftps lines?

As I showed, before the ftps() call.

#!/usr/bin/sh
set -u
typeset MYLOG=notification.log
typeset MYNOT=file.not.tmp
typeset MAILTO="you@your.net"
function ftps {
sleep 20
USER=anonymous
PW=xxxxx
ftp -v -i -n server_name << EOF
user ${USER} ${PW}
ascii
get ${MYLOG}
bye
EOF
}
rm -f ${MYLOG}
ftps
a=$(cat ${MYLOG}|head -n 5|sed 's/^.{45}//' > ${MYNOT})
while true
do
b=$(awk '{print $4}' ${MYNOT})
if [[ $b = "" ]]
then
mailx -s "CDR backup is completed in blbilstg server" ${MAILTO} < ${MYNOT}
break
fi
done

...

Regards!

...JRF...
Jeeshan
Honored Contributor

Re: Looping in a script

thanks again.

But i want if the pattern is not matched it again ftp the file and check accordingly until the matched found. If matched found than the program will terminate.
a warrior never quits
James R. Ferguson
Acclaimed Contributor

Re: Looping in a script

Hi (again):

OK, your loop could look like this:

...
while true
do
rm -f ${MYLOG}
ftps
a=$(cat ${MYLOG}|head -n 5|sed 's/^.{45}//' > ${MYNOT})
b=$(awk '{print $4}' ${MYNOT})
if [[ $b = "" ]]
then
mailx -s "CDR backup is completed in blbilstg server" ${MAILTO} < ${MYNOT}
continue
else
break
fi
done
...

Regards!

...JRF...
Dennis Handly
Acclaimed Contributor

Re: Looping in a script

>Doug: while [ "${b}" = "" ]

If you want a pattern instead of a simple string compare, you must use [[ ]]. And if you have a pattern, you must not use "".

>JRF: (1) Eliminate useless 'cat' processes!

Any reason you left this one? ;-)
a=$(cat ${MYLOG}|head -n 5|sed 's/^.{45}//' > ${MYNOT})

You could reverse the logic and save an indent for the main logic:
if [[ $b != ]]; then
break
fi
mailx -s "CDR backup is completed in blbilstg server" ${MAILTO} < ${MYNOT}