I also thought it would be better programming practice and improve the structure of the batch script to put function declarations at the top of the script together with variable declarations. In my own code, I'm standardizing on the labels "BEGIN" and "END" to de-mark the program execution area.
I greatly appreciated the FTP and Function tutorial portions of the DOS Tips website - it was a great help to me, since I needed an FTP script. I modified the DOS Tips code according to the structure I'm suggesting. I also added a little error handling - I write to the log file on a failure to download a given file but there are other things that could be done, such as sending an email or raising a popup on failure:
Code: Select all
@echo off
setlocal
rem -------------------------------------------------------------------
rem -----------------Global Variable declarations----------------------
rem -------------------------------------------------------------------
rem Date/time variables for file naming and date formatting
rem year, month, day, weekday, hour, minute, second
set vYr=%date:~10,4%
set vMon=%date:~4,2%
set vDay=%date:~7,2%
set vWkDay=%date:~0,3%
set vHr=%time:~0,2%
set vMn=%time:~3,2%
set vSec=%time:~6,2%
rem ---The following variables are for ease in maintaining & ---
rem ---changing common parameters in the batch job. ---
rem Set app name - used for logfile name.
set vAppName=WhateverApp
rem Set logfile name.
rem vLogfile variable can be configured to overwrite the log file each
rem time the job runs. It can also be configured to write a series of
rem logs and overwrite them every week, month, year or never.
rem Overwrite logfile each run
set "vLogFile=%vAppName%Log.txt"
rem Weekly series. Overwrite log files each week.
rem set vLogFile="%vAppName%Log %vWkDay%.txt"
rem Monthly series. Overwrite log files each month.
rem set vLogFile="%vAppName%Log %vDay%.txt"
rem Ininfite Series. Never overwrite log.
rem set vLogFile="%vAppName%Log %vYr%%vMon%%vDay%%vHr%%vSec%.txt"
rem FTP server name.
set "vFTPSvr=SomeFTPServer"
rem FTP server user name.
set "vFTPUser=SomeUsername"
rem FTP user password.
set "vFTPPass=SomePassword"
rem FTP directory where download file can be found.
set "vFTPDir=/some/FTP/directory"
rem Local directory where file will be placed.
set "vLocalDir=C:\Some\Destination\Computer\Folder"
rem Returning variable indicating if a function worked.
set "vResult=0"
rem -------------------------------------------------------------------
rem --------------------Function declarations--------------------------
rem -------------------------------------------------------------------
goto:BEGIN
:GetFile
rem This function creates the required feeder file for the FTP
rem app. Dependencies are vLogFile, vFTPSvr, vFTPUser, vFTPPass,
rem vFTPDir and vLocalDir.
rem Parameters are:
rem Param1 = Name of target file on FTP server
rem Param2 = Name of file after it has been downloaded.
rem Param3 = What to change the name of the file on the FTP server.
setlocal
rem load parameters into variables
rem Target FTP file name
set "vFTPFile=%~1%"
rem Name of FTP'd file on server
set "vLocalFile=%~2%"
rem New name of file on FTP server.
set "vRenameFile=%~3%"
rem ---Write commands to FTP Command file.---
rem Replace FTP Command file contents.
rem Connect to FTP server.
@echo open %vFTPSvr% > "%vAppName% FTP.txt"
@echo user %vFTPUser% %vFTPPass% >> "%vAppName% FTP.txt"
rem Change directories to desired locations.
@echo lcd "%vLocalDir%" >> "%vAppName% FTP.txt"
@echo cd "%vFTPDir%" >> "%vAppName% FTP.txt"
rem if the name of the target file is to be the same on both the
rem FTP server and the local server, construct the GET statement
rem to default to the same name in both places.
if "%vFTPFile%"=="%vLocalFile%" (
@echo get "%vFTPFile%" >> "%vAppName% FTP.txt"
)else (
@echo get "%vFTPFile%" "%vLocalFile%" >> "%vAppName% FTP.txt"
)
rem Do not add the rename portion of the code if the file on the
rem FTP server if the renaming is the same as the current name.
if not "%vRenameFile%"=="%vFTPFile%" (
@echo delete "%vRenameFile%" >> "%vAppName% FTP.txt"
@echo rename "%vFTPFile%" "%vRenameFile%" >> "%vAppName% FTP.txt"
)
rem Add code to close the FTP server connection and terminate the
rem FTP app.
@echo disconnect >> "%vAppName% FTP.txt"
@echo bye >> "%vAppName% FTP.txt"
rem goto:SkipFTP&rem Comment in for debugging.
rem Execute FTP step.
call ftp -i -n -s:"%vAppName% FTP.txt" >> %vLogFile%
:SkipFTP
rem goto:SkpDeCmd&rem Comment in for debugging.
rem Cleanup - delete FTP Command file.
if exist "%vAppName% FTP.txt" del /q "%vAppName% FTP.txt"
:SkpDeCmd
(endlocal
rem Return the number of times in the logfile that files were
rem successfully transferred from the FTP server.
set "%~4=0"
if exist "%vLogFile%" (
for /f "tokens=1,2,* skip=1" %%a in ('find /c "226 Transfer complete." %vLogFile%') do (
set "%~4=%%c"
)
)
)
exit /b 0
rem -------------------------------------------------------------------
rem --------------------Begin Program Execution------------------------
rem -------------------------------------------------------------------
:BEGIN
rem Switch to desired working directory
cd /d "C:\Directory\Where\I_Keep\Batch_Routines"
rem Overwrite existing or create new logfile with new load time
rem and load results.
@echo ---- Executed %date% %time% ---- > %vLogFile%
rem Retrieve files from FTP server.
call:GetFile "Some_FTP.txt", "Some FTP.txt", "Some_FTP.BU", vResult
if %vResult%==1 (
@echo ***Successfully downloaded Some_FTP.txt*** >> %vLogFile%
)else (
@echo ***Unable to download Some_FTP.txt*** >> %vLogFile%
goto:END
)
@echo. >> %vLogFile%&@echo. >> %vLogFile%
call:GetFile "SomeOther_FTP.txt", "Some Other FTP.txt", "SomeOther_FTP.bu", vResult
if %vResult%==2 (
@echo ***Successfully downloaded SomeOther_FTP.txt*** >> %vLogFile%
)else (
@echo ***Unable to download SomeOther_FTP.txt*** >> %vLogFile%
goto:END
)
@echo. >> %vLogFile%&@echo. >> %vLogFile%
:END
pause
endlocal
exit /b 0
exit
The double exit at the end assures that, if the program is called from another batch script, it terminates properly and returns control to the calling batch script.
Hope this helps someone.