1851088 Members
2979 Online
104056 Solutions
New Discussion

Yet Another FTP Script

 
Ron Brown_2
Frequent Advisor

Yet Another FTP Script

I'm drawing a blank on the test portion of this otherwise working script. Rather than checking for zero-length, I'd like to only put the file if the local copy is newer than the remote copy. Here's what I have:

#!/bin/sh
if [ -s /some/file ]
then

ftp -n host <
should work...
8 REPLIES 8
James R. Ferguson
Acclaimed Contributor

Re: Yet Another FTP Script

Hi Ron:

One way around this would be to retrieve the *remote* file's timestamp in an ftp session with 'modtime'. See the manpages for 'ftp'.

What you will have returned is something like:

/tmp/myfile 01/13/2006 17:40:06 GMT

You could then create a reference file whose modification timestamp matches the remote file timestamp and then compare the two file's timestamps with the 'test' operators ('-ot' or '-nt'). See the manpages for 'sh-posix'.

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: Yet Another FTP Script

Hi (again) Ron:

By the way, creating your reference file from the date and time string returned is merely a matter of parsing the date and time fields and applying them to a 'touch' command to create a reference file. Since your local time probably differs from the GMT (UTC) returned, and you want your timestamps synchronized to equivalent timezones for comparsion, do something like:

[ ftp modtime returned: 01/13/2006 17:40:06 GMT ]

# TZ=GMT UNIX95= touch -amt 01131740 /tmp/ref

Since, in my case, I am UTC-5 hours or EST, the remote file I queried was really modified at 12:40 EST. An 'ls -l' after the 'touch' will show the corrected, local timestamp of the file for proper comparison.

Regards!

...JRF...
Ivan Ferreira
Honored Contributor

Re: Yet Another FTP Script

I'm just wondering if you cannot use rsync or ssh/scp for your script.

Rsync only copy newer files if you configure to do that.

With ssh you can check the file dates and with scp you can transfer the files that you need.
Por que hacerlo dificil si es posible hacerlo facil? - Why do it the hard way, when you can do it the easy way?
Sundar_7
Honored Contributor

Re: Yet Another FTP Script

Try this Ron. May not be the most efficient but hope it works for you.

#!/bin/sh
if [ -s /some/file ]
then

(
echo "quote user username"
echo "quote pass password"
echo "lcd /usr/tmp"
echo "binary"
echo "get file /tmp/file_remote"
O=$(find . -name "file" -newer /tmp/file_remote | wc -l)
if [ $0 -gt 0 ]
then
echo "put file"
fi
echo "quit"
) | ftp -n host
fi
Learn What to do ,How to do and more importantly When to do ?
James R. Ferguson
Acclaimed Contributor

Re: Yet Another FTP Script

Hi (again):

The 'newer' option of 'ftp' is a variation of 'get'. Hence, the reason for my more round-about approach.

Regards!

...JRF...
Ron Brown_2
Frequent Advisor

Re: Yet Another FTP Script

Sundar:

Does this script not contain a logic error? The time stamp on the remote file will change to the time at which it was downloaded, thus always being newer than the local file.
should work...
James R. Ferguson
Acclaimed Contributor

Re: Yet Another FTP Script

Hi Ron:

In response to the suggestion to use 'newer', you wrote, "Does this script not contain a logic error? The time stamp on the remote file will change to the time at which it was downloaded, thus always being newer than the local file.".

This was exactly the reason I suggested my approach using 'modtime'.

You simply need to (1) open an ftp session to fetch the timestamp of the *remote* file that you *potentially* overwrite; (2) parse the returned timestamp string into a form suitable for creating a reference file with 'touch'; and (3) if the age relationship between the remote file (as know via the reference file) and the local file is suitable, then; (4) open a second ftp session to actually 'put' the file.

To fetch the timestamp information for parsing) simply collect it like this:

{ echo "open remotehost
user $user $passwd
modtime /path_to_remotefile
close"
} | ftp -i -n -v > /tmp/ftpresults

The file /tmp/ftpresults will contain the information you need to parse in step-2.

Regards!

...JRF...
James R. Ferguson
Acclaimed Contributor

Re: Yet Another FTP Script

Hi Ron:

I have the sense that what I have suggested thus far may not have been clear. Hence, here's the "preamble" to deduce whether or not your local file is newer than the remote version you want to potentially replace. In the spirt of Unix, this is but one way to accomplish your goal:

#!/usr/bin/sh
#@(#) Query age of remote file before ftp - JRF

typeset myfile=${1} #...file being handled...

typeset host=hhhhhhhh #...SPECIFY !
typeset user=uuuuuuuu #...SPECIFY !
typeset pass=pppppppp #...SPECIFY !

typeset ftpdata=/tmp/ftpdata.$$
typeset reffile=/tmp/reffile.$$

trap 'rm -f ${ftpdata} ${reffile}" > /dev/null 2>&1' EXIT

{ echo "open ${host}
user ${user} ${pass}
modtime ${myfile}
close"
} | ftp -i -n -v > ${ftpdata}

ts=`perl -wlne 'print "$3$1$2$4$5.$6"
if (m%\s+(\d+).(\d+).(\d+)\s+(\d+).(\d+).(\d+)\s+%)' ${ftpdata}`

[ -z "${ts}" ] && { echo "Can't query ${myfile}"; exit 1; }

TZ=GMT touch -amt ${ts} ${reffile} #...ftp modtime returns in GMT,,,

if [ ! -f "${myfile}" ];then
echo "no local version of ${myfile} exists"
elif [ "${myfile}" -nt "${reffile}" ]; then
echo "local version is NEWER than remote version"
else
echo "local version is OLDER than remote version"
fi

echo "...now do what you wish to FTP..."
exit 0

Regards!

...JRF...