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.