3

I have a .bat file that runs a ftp script, grabbing files from the server and copying them to my machine. Works great.

I now want this .bat file to report if any of these errors occured.

If you could point me in the right direction to the general idea of how to do this, that would be great.

Thanks.

5 Answers 5

4

To be honest I've never had great success using fixed FTP scripts. Even if you deal with the return codes its hard to know exactly what went wrong.

I'd recommend using PowerShell or Python for the job instead. Both these have access to an FTP client that can be dynamically controlled. You'll know exactly whats worked or failed, and be able to deal with the issue then and there.

Simple Example in PS

$url = "ftp://ftp.foo.com/bar.txt"
$destination = "c:\foo\bar.txt"
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($url, $destination)

If you need to do more complicated things I'd start by looking at http://msdn.microsoft.com/en-us/library/ms229718.aspx Those examples are in C#, but it should be pretty easy to convert them to PS.

A script built in this way can list a dir and loop over the files downloading the ones you want. If there are any errors you can handle them on a per file level how you like.

2

Here's how to do it in a BAT file.

Call FTP, while redirecting the output and errors to separate files. If the error file is nonblank, then there's an issue.

Assuming you've created set variables called FTPFILE, OUTPUTFILE and ERRORFILE, then the following should work:

  1. Call FTP, capturing output and errors to separate files.

    ftp -i -s:"%FTPFILE%" >"%OUTPUTFILE%" 2>"%ERRORFILE%"
    
  2. Check if the FTP call failed

    if  ERRORLEVEL 1 (
        echo Call to ftp returned an error. See file: %OUTPUTFILE%
        exit /b 1
    )
    
  3. Check if the FTP session contained errors. Do this by checking the size of the errorfile.

    FOR /F "usebackq" %%A IN ('%ERRORFILE%') DO set ERRORFILESIZE=%%~zA
    if %ERRORFILESIZE% GTR 0 ( 
        echo Error while performing the FTP. See file: %ERRORFILE%
        exit /b 2
    )
    
3
2

While Shez example above is a good standard way to capture errors from most dos based programs that set ERRORLEVEL and produce output from standard error (2>), ftp.exe out of the box from MS does not set ERRORLEVEL. ERRORLEVEL remains zero whether the script (-s: parameter) succeeds or fails. Redirecting standard error (2>) to "%ERRORFILE%" does not work either as this file will always be a zero byte file (because ftp.exe always returns ERROR_SUCCESS or 0) so only an empty file is created. So the command string:

ftp -i -s:"%FTPFILE%" >"%OUTPUTFILE%" 2>"%ERRORFILE%"

will never produce the expected results. If we are forced to use the Microsoft FTP client, the best bet is to parse through the %OUTPUTFILE% for certain text strings indicating an error or use a different FTP client other than MS's (like IPSWITCH WS_FTP) that allows for better error trapping. I will follow-up with code examples of how to parse through the %OUTPUTFILE% in a few hours once I finish coding it the brute force way. Thanks!

Follow-up

See my second post below for sample interactive Microsoft FTP session. Parsing example is next...OK what follows is a variation on Martijn S post on stackoverflow.com here. My solution uses FINDSTR and a separate text file containing search criteria:

Create a text file (FTP_ERR_SEARCH_CRITERIA.txt) containing the following text strings:

not connected
not found
failed

Call the following subroutine from your batch/command file:

::
::=============================================================================
:WIN_FTP_ERROR %1=%_SearchCriteria% %2=%_InputFile%
::=============================================================================
::
    set _SearchCriteria=%1
    set _InputFile=%2
    set _tokens="tokens=*"
    for /F %_tokens% %%G in ('findstr /I /G:%_SearchCriteria% %_InputFile%') do @echo "%%G"
exit /b

The call:

call :WIN_FTP_ERROR ".\FTP_ERR_SEARCH_CRITERIA.txt" %OUTPUTFILE%

Sample Microsoft FTP Output

Continuing where I left off... Sometimes the best way to find out how something works is to test it yourself rather than rely on the plethora of misinformation found on the internet. So here it goes. The example below shows two different files: tst.txt and tst.tx (subtle difference in the name but different just the same). The tst.txt file exists while the tst.tx does not.

Microsoft FTP Example (spacing added for clarity):

ftp> put tst.txt
200 PORT command successful.
150 Opening ASCII mode data connection for tst.txt.
226 Transfer complete.
ftp: 44 bytes sent in 0.19Seconds 0.24Kbytes/sec.

ftp> put tst.tx
tst.tx: File not found

ftp> get tst.tx
200 PORT command successful.
550 tst.tx: The system cannot find the file specified.

ftp> get tst.txt
200 PORT command successful.
150 Opening ASCII mode data connection for tst.txt(44 bytes).
226 Transfer complete.
ftp: 44 bytes received in 0.00Seconds 44000.00Kbytes/sec.

Note how the local file system and remote file system respond to the commands above:

for the first put tst.txt command (the file exists on the local file system) we see that the remote server responds by transferring the file.

for the second put tst.tx command (the file tst.tx does not exist on either system) we see that the local file system responds with the filename tst.tx and the error message File not found

for the third get tst.tx command (again the file tst.tx does not exist) we see that the remote file system (actually remote FTP host) responds with the FTP error code 550, the filename tst.tx and the error message The system cannot find the file specified.

for the fourth and final get tst.txt command (the file now exists on the remote system) we see that the remote system responds with a successful transfer.

Why all this explanation? It matters when we parse through the file in the previous post to see what the error messages are coming back from MS ftp.exe.

1

It's common for console utilites to return some code indicating that error was happened, they are described e.g. here. If ftp exits after some error it probably returns a non-zero code indicating fault. IMHO there is no simple way to parse output of a program in batch files, but you can check errorlevel and save a logfile (using output stream redirection: command args >log) or send it by email.

3
  • Are there any ftp specific error levels, indicators of what the error was, or am I only given "something" went wrong? Thank You.
    – Tommy
    Jan 21, 2010 at 20:09
  • Looks like this is a custome error check: experts-exchange.com/OS/Microsoft_Operating_Systems/MS_DOS/…
    – Tommy
    Jan 21, 2010 at 20:11
  • Yes, that script is parsing ftp's output (it does not use ftp errorlevels, only find). It is what I called 'complicated' in my post, through. Sorry, I cannot provide you more detail about batch files and ftp because I do not have an accessible Windows system now.
    – Catherine
    Jan 21, 2010 at 20:27
1

That error message is a FTP specific error, and is because your firewall will by default disable FTP connections (this is a good thing!).

You can ignore this message as it will not affect your computer in any way.

Not the answer you're looking for? Browse other questions tagged .