Batch Variable Conflict
Can somebody help to fix the below:

@echo off
setlocal EnableDelayedExpansion

set formatted_source="C:\Test\*.txt"

:: Above directory contains a file named as abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&^%$#@!`~.txt

set formatted_source_file="C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&^%$#@!`~.txt"
set formatted_dest="C:\backup"

call :copyVerifyMove !formatted_source_file! !formatted_dest!

if "!formatted_source!" NEQ "" (
for %%l in ("!formatted_source!") do (
set formatted_source_file1="%%l"
call :copyVerifyMove !formatted_source_file1! !formatted_dest!
)
)
goto :eof


:copyVerifyMove
echo.%1
echo.%2
pause

I am just trying to figure out why it is not working in 2nd call (and why working in 1st call)
April 27th, 2015 12:01pm

It seems to me that Caret is creating the problem



Free Windows Admin Tool Kit Click here and download it now
April 27th, 2015 12:18pm

I am just trying to figure out why it is not working in 2nd call (and why working in 1st call)

Your batch file is not working on the first subroutine call. It fails to echo some of the poison characters such as ^, %, !.

I consider this exercise somewhat futile. By selecting batch as a scripting language you knowingly choose a tool that has well-known limitations. If you want a robust script then you must eliminate the poison characters from your file names or else use a scripting language that can deal with them without contorsions.

April 27th, 2015 12:48pm

It seems to me that Caret is creating the problem



Free Windows Admin Tool Kit Click here and download it now
April 27th, 2015 4:17pm

It seems to me that Caret is creating the problem



April 27th, 2015 4:17pm

you need to add goto:eof in :copyVerifyMove to return to the next line of the caller.

Otherwise, it just continue to pause statement and batch will exit.

I have tested your script and it works as you expected.

:copyVerifyMove
echo.%1
echo.%2

goto:eof
pause

Output of script:

F:\>test1.cmd

F:\>setlocal EnableDelayedExpansion

F:\>set formatted_source="C:\Test\*.txt"

F:\>set formatted_source_file="C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&^$#@!`~.t
xt"

F:\>set formatted_dest="C:\backup"

F:\>call :copyVerifyMove !formatted_source_file! !formatted_dest!

F:\>echo."C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&$#@`~.txt"
"C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&$#@`~.txt"

F:\>echo."C:\backup"
"C:\backup"

F:\>goto:eof

F:\>if "!formatted_source!" NEQ "" (for %l in ("!formatted_source!") do (
set formatted_source_file1="%l"
 call :copyVerifyMove !formatted_source_file1! !formatted_dest!
) )

F:\>(
set formatted_source_file1="C:\Test\tset1.txt"
 call :copyVerifyMove !formatted_source_file1! !formatted_dest!
)

F:\>echo."C:\Test\tset1.txt"
"C:\Test\tset1.txt"

F:\>echo."C:\backup"
"C:\backup"

F:\>goto:eof

F:\>goto :eof


  • Edited by ylnotes 16 hours 7 minutes ago
Free Windows Admin Tool Kit Click here and download it now
April 28th, 2015 10:58am

you need to add goto:eof in :copyVerifyMove to return to the next line of the caller.

Otherwise, it just continue to pause statement and batch will exit.

I have tested your script and it works as you expected.

:copyVerifyMove

This is not correct. The subroutine "CopyVerifyMove" is the last (and only) subroutine in the OP's script. Adding the statement "goto :eof" at its end makes no difference whatsoever.
April 28th, 2015 11:48am

you need to add goto:eof in :copyVerifyMove to return to the next line of the caller.

Otherwise, it just continue to pause statement and batch will exit.

I have tested your script and it works as you expected.

:copyVerifyMove
echo.%1
echo.%2

goto:eof
pause

Output of script:

F:\>test1.cmd

F:\>setlocal EnableDelayedExpansion

F:\>set formatted_source="C:\Test\*.txt"

F:\>set formatted_source_file="C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&^$#@!`~.t
xt"

F:\>set formatted_dest="C:\backup"

F:\>call :copyVerifyMove !formatted_source_file! !formatted_dest!

F:\>echo."C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&$#@`~.txt"
"C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&$#@`~.txt"

F:\>echo."C:\backup"
"C:\backup"

F:\>goto:eof

F:\>if "!formatted_source!" NEQ "" (for %l in ("!formatted_source!") do (
set formatted_source_file1="%l"
 call :copyVerifyMove !formatted_source_file1! !formatted_dest!
) )

F:\>(
set formatted_source_file1="C:\Test\tset1.txt"
 call :copyVerifyMove !formatted_source_file1! !formatted_dest!
)

F:\>echo."C:\Test\tset1.txt"
"C:\Test\tset1.txt"

F:\>echo."C:\backup"
"C:\backup"

F:\>goto:eof

F:\>goto :eof


  • Edited by ylnotes Tuesday, April 28, 2015 3:01 PM
Free Windows Admin Tool Kit Click here and download it now
April 28th, 2015 2:55pm

you need to add goto:eof in :copyVerifyMove to return to the next line of the caller.

Otherwise, it just continue to pause statement and batch will exit.

I have tested your script and it works as you expected.

:copyVerifyMove
echo.%1
echo.%2

goto:eof
pause

Output of script:

F:\>test1.cmd

F:\>setlocal EnableDelayedExpansion

F:\>set formatted_source="C:\Test\*.txt"

F:\>set formatted_source_file="C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&^$#@!`~.t
xt"

F:\>set formatted_dest="C:\backup"

F:\>call :copyVerifyMove !formatted_source_file! !formatted_dest!

F:\>echo."C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&$#@`~.txt"
"C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&$#@`~.txt"

F:\>echo."C:\backup"
"C:\backup"

F:\>goto:eof

F:\>if "!formatted_source!" NEQ "" (for %l in ("!formatted_source!") do (
set formatted_source_file1="%l"
 call :copyVerifyMove !formatted_source_file1! !formatted_dest!
) )

F:\>(
set formatted_source_file1="C:\Test\tset1.txt"
 call :copyVerifyMove !formatted_source_file1! !formatted_dest!
)

F:\>echo."C:\Test\tset1.txt"
"C:\Test\tset1.txt"

F:\>echo."C:\backup"
"C:\backup"

F:\>goto:eof

F:\>goto :eof


  • Edited by ylnotes Tuesday, April 28, 2015 3:01 PM
April 28th, 2015 2:55pm

OP uses CALL:<LABEL> to process something like procedure. 

To return to the caller CALL:<LABEL>, you need to add GOTO:EOF and it will return to end of CALL:<LABEL> and continue next line of script.

Batch does not have the concept of procedure like in other language like vbscript. However, you can use CALL:<LABEL> to work like procedure.

If you do not set GOTO:EOF in CALL:<LABEL>, it will continue to proceed to execute next statement in CALL:<LABEL> until it reach the end of line.

This is how batch file works, and it may be difficult to understand if you have learned advanced scripting such as vbscript, powershell, etc. 

I create a sample script to better illustrate the working.

Enjoy

Batch Script

@ECHO ON

	ECHO BEFORE CALL PROC1
CALL:PROC1
	ECHO AFTER CALL PROC1

	ECHO BEFORE CALL PROC2
CALL:PROC2
	ECHO AFTER CALL PROC2
	
PAUSE
GOTO:EOF

	ECHO PROC1: BEFORE
:PROC1
	ECHO PROC1: INSIDE
GOTO:EOF
	ECHO PROC1: AFTER

	
	ECHO PROC2: BEFORE
:PROC2
	ECHO PROC2: INSIDE
GOTO:EOF
	ECHO PROC2: AFTER
	

	

Script output

F:\>test2.cmd

F:\>ECHO BEFORE CALL PROC1
BEFORE CALL PROC1

F:\>CALL:PROC1

F:\>ECHO PROC1: INSIDE
PROC1: INSIDE

F:\>GOTO:EOF

F:\>ECHO AFTER CALL PROC1
AFTER CALL PROC1

F:\>ECHO BEFORE CALL PROC2
BEFORE CALL PROC2

F:\>CALL:PROC2

F:\>ECHO PROC2: INSIDE
PROC2: INSIDE

F:\>GOTO:EOF

F:\>ECHO AFTER CALL PROC2
AFTER CALL PROC2

F:\>PAUSE
Press any key to continue . . .

Free Windows Admin Tool Kit Click here and download it now
April 29th, 2015 10:59am

OP uses CALL:<LABEL> to process something like procedure. 

To return to the caller CALL:<LABEL>, you need to add GOTO:EOF and it will return to end of CALL:<LABEL> and continue next line of script.

Batch does not have the concept of procedure like in other language like vbscript. However, you can use CALL:<LABEL> to work like procedure.

If you do not set GOTO:EOF in CALL:<LABEL>, it will continue to proceed to execute next statement in CALL:<LABEL> until it reach the end of line.

Please run the following two batch files, then review the above statements. According to you, Batch File 1 should not work. It uses the structure that the OP used. Yet it works perfectly.

Batch File 1
@echo off
for %%a in (1 2 3) do call :Sub %%a
goto :eof
:Sub
echo The parameter is %1

Batch File 2@echo off
for %%a in (1 2 3) do call :Sub %%a
goto :eof
:Sub
echo The parameter is %1
goto :eof


April 29th, 2015 11:22am

OP uses CALL:<LABEL> to process something like procedure. 

To return to the caller CALL:<LABEL>, you need to add GOTO:EOF and it will return to end of CALL:<LABEL> and continue next line of script.

Batch does not have the concept of procedure like in other language like vbscript. However, you can use CALL:<LABEL> to work like procedure.

If you do not set GOTO:EOF in CALL:<LABEL>, it will continue to proceed to execute next statement in CALL:<LABEL> until it reach the end of line.

Please run the following two batch files, then review the above statements. According to you, Batch File 1 should not work. It uses the structure that the OP used. Yet it works perfectly.

Batch File 1
@echo off
for %%a in (1 2 3) do call :Sub %%a
goto :eof
:Sub
echo The parameter is %1

Batch File 2@echo off
for %%a in (1 2 3) do call :Sub %%a
goto :eof
:Sub
echo The parameter is %1
goto :eof


Free Windows Admin Tool Kit Click here and download it now
April 29th, 2015 3:20pm

OP uses CALL:<LABEL> to process something like procedure. 

To return to the caller CALL:<LABEL>, you need to add GOTO:EOF and it will return to end of CALL:<LABEL> and continue next line of script.

Batch does not have the concept of procedure like in other language like vbscript. However, you can use CALL:<LABEL> to work like procedure.

If you do not set GOTO:EOF in CALL:<LABEL>, it will continue to proceed to execute next statement in CALL:<LABEL> until it reach the end of line.

Please run the following two batch files, then review the above statements. According to you, Batch File 1 should not work. It uses the structure that the OP used. Yet it works perfectly.

Batch File 1
@echo off
for %%a in (1 2 3) do call :Sub %%a
goto :eof
:Sub
echo The parameter is %1

Batch File 2@echo off
for %%a in (1 2 3) do call :Sub %%a
goto :eof
:Sub
echo The parameter is %1
goto :eof


April 29th, 2015 3:20pm

Hi Frederik,

My statement is referring to call:copyVerifyMove on first call as in OP script.

If goto eof is not set in subroutine  call:copyVerifyMove, it will continue to end and second call  call:copyVerifyMove is never executed.

Your sample script, yes, it does work but it behaves differently.

My test shows that for loop somehow process each call separately and will execute sub routine to end of script and continue with second loop and so on.

Hope it clarifies


@echo on
setlocal EnableDelayedExpansion

set formatted_source="C:\Test\*.txt"

:: Above directory contains a file named as abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&^%$#@!`~.txt

set formatted_source_file="C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&^%$#@!`~.txt"
set formatted_dest="C:\backup"

echo before call:copyVerifyMove [1]
call :copyVerifyMove !formatted_source_file! !formatted_dest!
echo after call:copyVerifyMove [1]

echo before call:copyVerifyMove [2]
if "!formatted_source!" NEQ "" (
for %%l in ("!formatted_source!") do (
set formatted_source_file1="%%l"
call :copyVerifyMove !formatted_source_file1! !formatted_dest!
)
)
echo after call:copyVerifyMove [2]
goto :eof


:copyVerifyMove
echo inside call:copyVerifyMove
echo inside call:copyVerifyMove: output
echo.%1
echo.%2
pause
batch output:
D:\>setlocal EnableDelayedExpansion

D:\>set formatted_source="C:\Test\*.txt"

D:\>set formatted_source_file="C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'
[]{}=+-_)(&^$#@!`~.txt"

D:\>set formatted_dest="C:\backup"

D:\>echo before call:copyVerifyMove [1]
before call:copyVerifyMove [1]

D:\>call :copyVerifyMove !formatted_source_file! !formatted_dest!

D:\>echo inside call:copyVerifyMove
inside call:copyVerifyMove

D:\>echo inside call:copyVerifyMove: output
inside call:copyVerifyMove: output

D:\>echo."C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&$#@`~.txt"

"C:\Test\abcdefghijklmnopqrstuvwxyz1234567890, .;'[]{}=+-_)(&$#@`~.txt"

D:\>echo."C:\backup"
"C:\backup"

D:\>pause
Press any key to continue . . .

Free Windows Admin Tool Kit Click here and download it now
April 30th, 2015 6:01am

I note that your mind is made up. There is no point in trying to confuse you with facts.
April 30th, 2015 8:52am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics