@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)
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.
It seems to me that Caret is creating the problem
- Edited by Himanshumhm Monday, April 27, 2015 4:22 PM
It seems to me that Caret is creating the problem
- Edited by Himanshumhm Monday, April 27, 2015 4:22 PM
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
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.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
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
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
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 . . .
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
- Edited by Frederik LongMicrosoft community contributor 15 hours 47 minutes ago
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
- Edited by Frederik LongMicrosoft community contributor Wednesday, April 29, 2015 3:21 PM
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
- Edited by Frederik LongMicrosoft community contributor Wednesday, April 29, 2015 3:21 PM
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 pausebatch 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 . . .