Ftp scripting question

Hi guys,

I'm trying to create an ftp script that will read in a value from input, then search for files with the input value, and then ftp the files..

So far I've got my read answer set up, and it'll ls -lrt out my files with the value read answer var I given it...

My question is, what would be the best way to ftp these files... There'll be around 31 one of these files, so I don't want to write 31 separate ftp commands in the script..

Is there a way to pass the files somehow to the one ftp command? I know how to make driver files but can't figure out how I'd pass the info into one and get it to work..

Any suggestions what the best way to do this would be?

Thanks,
Jaz

**EDIT**
Using .ksh if it makes any difference

I am just giving a basic idea and you can modify it as per your requriment


servername="xx.x.xx.xx";
username="user";
password="pswd";

var=`ls`
cmd=`echo mput $var`
echo $cmd

ftp -nv $servername <<EOF > ftp.log
user $username $password
prompt
$cmd
EOF

mput - will ftp multiple files(with interatcive mode by default)
prompt - will toggle the interactive mode "on" and "off"

Hope this is something what you are looking for!

Regards
Dileep

Ok, not sure how that would work for me...

The script is going to be used to ftp files from an archive dir.. When the script is run it will ask the user for the date of the files they're looking for.
It will then list out the files (which will look like LTR1.txt-20081016 and on confirmation will ftp them..
This is what I have so far. The ftp part will happen in the first part of the 'then' statemen.

echo "Please enter the date of the files you are looking for in the format yyyymmdd"
read answer

SFILE=LTR*-$answer*
ls -lrt $SFILE | cut -d " " -f 22
#
echo ""
echo "Are these the correct files you want to see?"
read answer1
if [ "$answer1" = "Y" ] || [ "$answer1" = "y" ]
then

The ftp will need to drop the archive date when its sending the file. So instead of LTR1.txt-20081016, it'll send LTR1.txt. Not sure if your way is what i'm looking for but it's a good start..

Try this:

SFILE=LTR*-$answer*
ls -rt $SFILE
#
echo ""
echo "Are these the correct files you want to see?"
read answer1
if [[ "$answer1" = [Yy] ]]
then
        ls -rt $SFILE | awk '
                BEGIN { print "user username password" }
                {
                        srcfile=$1
                        destfile=$1
                        sub("-[0-9]{8}$","",destfile)
                        print "put",srcfile,destfile
                }
                END { print "bye" }
        ' | ftp -nv hostname
fi

Naturally you will need to change username, password and hostname to appropriate values. Note that I changed the cut -d " " -f22 as it didn't work on the system I was testing on, and it's unnecessary anyway if you just leave out the -l.

Wow, thanks man... I'll have to test it out in a bit to see if it works for me..
Where about would you put where you want destination folder to be?

Can you explain how some of the code works?

What does the BEGIN do?
What does the line sub("-[0-9]{8}$","",destfile) actually do?
And should there be $ before srcfile & destfile in the line print "put",srcfile,destfile are they not variables?

Thanks for your help?

I've colourised my previous post slightly. The part highlighted in avocado green is an awk script, not normal shell script, so the language is a little different. That's why the variables don't have $'s in front of them.

The BEGIN clause is processed before awk reads any of the input (which it reads from stdin). Similarly the END clause is processed after it has finished reading all the input. Any other expression { commands } clauses are processed whenever the expression is true, but in the case of this script I've left out the expression because we want to execute the prints for every input line. See man awk for more details about the awk language.

The sub() function substitutes a dash followed by 8 digits with nothing in the destination filename.

Thanks for that, had done a man awk and read up a little on it..

Was wondering where about I would put where the destination folder command?
I thought it would go within the awk script like below, but I'm not sure if i'm correct. Can you clear this up for me

ls -rt $SFILE | awk '
BEGIN { print "user username pwd" }
{
srcfile=$1
destfile=$1
sub("-[0-9]{8}$","",destfile)
print "cd /home/test_files"
print "put",srcfile,destfile
}
END { print "bye" }

If you comment out the ftp command (e.g. ' #| ftp -nv hostname), then you will see what effect your changes are having without causing any damage. :slight_smile:

You really want to add the cd to the BEGIN section, because you only need to do that once at the start, not once for each file.

Thanks for your help on this.. You can guess I'm not that good at this!

Ok, I'm guessing its gonna go something like this

ls -rt $SFILE | awk '
BEGIN { print "user username pwd"
print "cd /home/test_files"}
{
srcfile=$1
destfile=$1
sub("-[0-9]{8}$","",destfile)
print "put",srcfile,destfile
}
END { print "bye" }

Let us know how it goes!

It half worked. :rolleyes:

The files were sent but the date stamp wasn't dropped...

Some awks may not understand the {8} syntax, in which case you can either try nawk (may be available on some OS - which one are you using by the way?), or use a different syntax, either -[0-9]+ or -[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] (horrible, I know).

On AIX 5.2.

Tried to man nawk but there's no man page for it.. doubt its available to me..

Should i try those other suggestions with out the {8} ?

**EDIT**
Just did a print destfile to see what was spat out when i used -[0-9]+ and success.... She works beautifully...
Thanks for all your help man, your a legend

Ok, back with this again... I want to do some error checking on my ftp command.. I had set up so that it would dump everything out to a log file and then I would grep that log file for known errors. i.e

 
        ls -rt $SFILE | awk '
                BEGIN { print "user username pwd"
                        print "binary"
                        print "cd /home/test_files" }
                {
                        srcfile=$1
                        destfile=$1
                        sub("-[0-9]+$","",destfile)
                        print "put",srcfile,destfile
                }
                END { print "bye" }
        '| ftp -nv Servername >> $LOG
	  err=$?
        if (( 0 != $( grep -i 'Not connected' $LOG | wc -l ) ))  ||
           (( 0 != $( grep -i 'not authorized' $LOG | wc -l ) ))  ||
           (( 0 != $( grep -i 'file access permissions do not allow' $LOG | wc -l ) ))  ||
           (( 0 != $( grep -i 'Login failed' $LOG | wc -l ) ))  ||
           (( 0 != $( grep -i 'Mismatched' $LOG | wc -l ) ))  ||
           (( 0 != $( grep -i 'ABOR' $LOG | wc -l ) ))  ||
           (( 0 != $( grep -i ' No such file' $LOG | wc -l ) )) ||
           (( 0 != $( grep -i 'Allocated to another' $LOG | wc -l ) ))  ||
           (( 0 != $( grep -i 'not found' $LOG | wc -l ) )) then
           echo "Problem with FTP process, `date`" >> $LOG
           echo "Problem with FTP process, files were not sent out"
           echo ""
           echo "Please check $LOG for more information"
           exit 1
        else

However, this isn't very efficient as the grep happens after the ftp process has happened. There's the potential to lock out an account this way. I'd rather catch an invalid pwd in realtime and any other errors during the ftp.

Can if statements be performed inside the awk?
Is it the same syntax as ksh?
Any suggestions?

Don't worry about locking out the account; if the login fails the fact that any subsequent commands fail won't affect the destination account. It will only count as one failed login.

Yes, if statements can be performed in awk, but the problem is that the awk can not see the output of the FTP command, it is just generating a list of commands that are piped into FTP.

You can simplify the error-checking block using the following:

        if grep -Eqi 'Not connected|not authorized|file access permissions do not allow|Login failed|Mismatched|ABOR| No such file|Allocated to another|not found'  $LOG
        then
           echo "Problem with FTP process, `date`" >> $LOG
           echo "Problem with FTP process, files were not sent out"
           echo ""
           echo "Please check $LOG for more information"
           exit 1
        else

Depending on your OS it may be egrep -qi rather than grep -Eqi. Also, if the -q option (quiet) is not available, simply redirect the output of the grep to /dev/null.