Link to home
Start Free TrialLog in
Avatar of gracie1972
gracie1972Flag for United States of America

asked on

BAT FILE ERROR LOG Question

I am writing a bat file to copy files from one folder to the next.   I added a line to capture error messages.

@echo off
call "H:\MSTR_TEST\BAT\MSTR_SALES_CHANNEL.BAT" >"H:\MSTR_TEST\BAT\mybatch.log" 2>&1
start "" notepad "H:\MSTR_TEST\BAT\mybatch.log"

However the log file only shows:
        0 file(s) copied.
The system cannot find the file specified.

Is there a way to capture what the file name was that was not copied?
Avatar of oBdA
oBdA

Not inside that script; you'll need to adjust MSTR_SALES_CHANNEL.BAT, so that it either prints out the file(s) it's trying to copy prior to the copy command, or (probably better) by using robocopy.exe, which is more verbose than copy.
Avatar of gracie1972

ASKER

I am not that versed in BAT files, what do you mean by robocopy?
robocopy.exe; part of the OS since Vista.
I'd help further, but that's impossible without information about the script that does the actual copying.
Essentially I have about 486 files each week to copy.

Here is what the script looks like (Replicated many times by file name):
Copy "T:\123\MSTR_Reporting\Finance\Shared\CSP 123 Fiscal Quarter SALES CHANNEL_HOME FIELD.PDF" "T:\123\MSTR_Reporting\SALES\Shared\HOME FIELD\CSP 123 Fiscal Quarter SALES CHANNEL_HOME FIELD.PDF"
Okay; there might be better solutions, but in trying to keep the necessary changes to a minimum, you can do the following, assuming you have 486 lines all like your example:
1. After the usual backup, open the batch file in Notepad++ (https://notepad-plus-plus.org/). Use Column mode edit to add "call :LogAnd" (minus the quotes, don't forget the ":") immediately before each such line. Hint: set the cursor at the beginning of the first line; now move the mouse (not the cursor!) to the beginning of the last such line, hold Shift and Alt down, and left-click; you now have one very, very long cursor in column 1, and can type away. The "copy" lines should now look like this:
call :LogAndCopy "<Source>" "<Destination>"

Open in new window

Now at the very end of the batch, add the following:
REM *** Function only below this line
goto :eof
:LogAndCopy <Source> <Destination>
echo Copying %1 to %2 ...
copy %1 %2
if errorlevel 1 echo ERROR.
goto :eof

Open in new window

The whole script should now look like this:
REM Other batch content ...
call :LogAndCopy "T:\123\MSTR_Reporting\Finance\Shared\CSP 123 Fiscal Quarter SALES CHANNEL_HOME FIELD.PDF" "T:\123\MSTR_Reporting\SALES\Shared\HOME FIELD\CSP 123 Fiscal Quarter SALES CHANNEL_HOME FIELD.PDF"
call :LogAndCopy "T:\456\MSTR_Reporting\Finance\Shared\CSP 456 Fiscal Quarter SALES CHANNEL_HOME FIELD.PDF" "T:\456\MSTR_Reporting\SALES\Shared\HOME FIELD\CSP 456 Fiscal Quarter SALES CHANNEL_HOME FIELD.PDF"
REM Other batch content ...

REM *** Function only below this line
goto :eof
:LogAndCopy <Source> <Destination>
echo Copying %1 to %2 ...
copy %1 %2
if errorlevel 1 echo ERROR.
goto :eof

Open in new window

You should now have a full log, and can search for "ERROR" (another hint: Notepad++ and the "Find all in current document" comes in handy for this sort of thing).
That didnt do anything,  <Source> <Destination>

goto :eof
:LogAndCopy <Source> <Destination>

:LogAndCopy "log.txt" "T:\123\MSTR_Reporting\Finance\Shared\MSTR_TEST\BAT\"  >> IS THIS CORRECT?

echo Copying %1 to %2 ...
copy %1 %2
if errorlevel 1 echo ERROR.
goto :eof
Do not change anything in the second code box above.
All you have to do is add "call :LogAndCopy" immediately in front of every "Copy" line, and then add the code from the second block at the very end of your script.
The third code box gives an example of how your changed script should look like.
Like this:

<< Beginning of code >>

goto :eof
:LogAndCopy "log.txt" "T:\123\MSTR_Reporting\Finance\Shared\MSTR_TEST\BAT\"

call :LogAndCopy Copy "T:\123\\MSTR_Reporting\Finance\Shared\BEAT 123 LEAD REP_S88888, Jennifer.XLSX" "T:\123\MSTR_Reporting\SALES\HOME FIELD\Shared\ASPIRATIONAL\REPS\BEAT 123 LEAD REP_S8888, Jennifer.XLSX"

<<End of Code>>

echo Copying %1 to %2 ...
copy %1 %2
if errorlevel 1 echo ERROR.
goto :eof
No; again: "Do not change anything in the second code box above."
I don't know how to explain it more clearly:
1. Add "call :LogAnd" immediately in front of every "Copy" line in your old script, so that these lines look like this:
call :LogAndCopy "T:\123\MSTR_Reporting\Finance\Shared\CSP 123 Fiscal Quarter SALES CHANNEL_HOME FIELD.PDF" "T:\123\MSTR_Reporting\SALES\Shared\HOME FIELD\CSP 123 Fiscal Quarter SALES CHANNEL_HOME FIELD.PDF"

Open in new window

2. Add the following code block at the very end of the script, without changing anything:
REM *** Function only below this line; POSITIVELY NO CHANGES WHATSOEVER BELOW THIS LINE!
goto :eof
:LogAndCopy <Source> <Destination>
echo Copying %1 to %2 ...
copy %1 %2
if errorlevel 1 echo ERROR.
goto :eof

Open in new window

Okay and thank you.  The code copies and no logs are generated.  

1) I opened the file to lock the excel file
2) Ran my BAT file. ran and
3) No log file was created.
4) No file was copied over either.....any thoughts?

<<CODE>>

call :LogAndCopy "T:\123\MSTR_Reporting\Finance\Shared\BEAT adidas LEAD REP_DXXXX, Scott.XLSX" "T:\123\MSTR_Reporting\SALES\COMMERCIAL\Shared\FAMILY FOOTWEAR\REPS\BEAT adidas LEAD REP_DXXXX, Scott.XLSX"

REM *** Function only below this line; POSITIVELY NO CHANGES WHATSOEVER BELOW THIS LINE!

goto :eof
:LogAndCopy "log.txt" "H:\MSTR_TEST\BAT"
echo Copying %1 to %2 ...
copy %1 %2
if errorlevel 1 echo ERROR.
goto :eof
If you run the script manually from an already open(!) command prompt, you should see console output indicating which files are copied.
The code as it is will not log anything to a text file, as you already had the wrapper script you mentioned above, and I wanted to keep the changes to your script to a minimum.

And with "without changing anything" and "POSITIVELY NO CHANGES WHATSOEVER BELOW THIS LINE", I actually meant "without changing anything" and "POSITIVELY NO CHANGES WHATSOEVER BELOW THIS LINE".
Luckily enough, changing <Source> and <Destination> doesn't have an impact, though. It's just garnish after a label that indicates which argument has which meaning. Change it back anyway, it's confusing otherwise.
Okay I tried the code still works, just nothing logs.   You mentioned the code as is will not create a log.  How can I do this?  We just need to log the file name that did not copy over.
ASKER CERTIFIED SOLUTION
Avatar of oBdA
oBdA

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank You!!!!!
I tested with all the files now. It copies the ERROR perfectly.  
It also copies everything else.  Can we modify to only copy if there is an ERROR only?
You mean "log", not copy?
REM Path and name of the log file (no quotes):
set LogFile=H:\MSTR_TEST\BAT\mybatch.log
REM *** Function only below this line; POSITIVELY NO CHANGES WHATSOEVER BELOW THIS LINE!
goto :eof
:LogAndCopy <Source> <Destination>
copy %1 %2 >NUL 2>>&1
if errorlevel 1 (
	>>"%LogFile%" echo ERROR copying %1 to %2
)
goto :eof

Open in new window

Yes I mean log and thank you this worked better.