0

I looked through all of the previously asked similar questions but couldn't find the answer.

I have a batch file that creates new batch files with specific text inside them, the text is taken from a specific directory. It works great, but right now a lot of code is repeated multiple times, and should be automated.

Here is the working code that I have:

set /p x=<"path were all the source files are kept\FileOne.txt"
set x=%x:~20%
set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
break> FileOne.bat
echo %y% >>FileOne.bat

First line opens a specific directory, opens a text file and saves the first line of it as x.

The second then removes the first 20 symbols from it, leaving only the needed part.

The third line sets Y to the command I need inside the newly created batch file and puts X at the end of it.

Then Y is saved as an output .bat file.

This code is repeated again and again for FileTwo, FileThree, FIleFour and so on.

Here is how I tried to turn it into a loop:

etlocal enabledelayedexpansion

FOR %%A in (FileOne FileTwo) DO (

set /p x=<"path were all the source files are kept\%%A.txt"
set x=%x:~20%
set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
break> %%A.bat
echo %y% >>%%A.bat

)

The two files are created as planned, but both of them had Echo is Off inside (or, when I turned it on, Echo is On).

Here is the console output:

C:\>setlocal enabledelayedexpansion

C:\>FOR %A in (FileOne FileTwo) DO (
set /p x= 0<"path were all the source files are kept\%A.txt"
 set x=~20
 set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
 break1>%A.bat
 echo   1>>%A.bat
)

C:\>(
set /p x= 0<"path were all the source files are kept\FileOne.txt"
 set x=~20
 set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
 break1>FileOne.bat
 echo   1>>FileOne.bat
)

C:\>(
set /p x= 0<"path were all the source files are kept\FileTwo.txt"
 set x=~20
 set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz %x%
 break1>FileTwo.bat
 echo   1>>FileTwo.bat
)

I see that it did make the loop, and created the files, but some commands look corrupt for some reason. Is there a special way I need to declare and use other variables inside a loop in a .bat file?

0

3 Answers 3

4

Within a block statement (a parenthesised series of statements), the entire block is parsed and then executed. Any %var% within the block will be replaced by that variable's value at the time the block is parsed - before the block is executed - the same thing applies to a FOR ... DO (block).

Hence, IF (something) else (somethingelse) will be executed using the values of %variables% at the time the IF is encountered.

In your case, y and x are each being set within the loop, so their values when the loop was parsed are used. In all probability, these values were empty so for instance echo %y% would be interpreted as echo and hence the current echo state would be reported.

Two common ways to overcome this are:

  1. Use setlocal enabledelayedexpansion and use !var! in place of %var% to access the changed value of var, or
  2. Call a subroutine to perform further processing using the changed values.

So, to solve, add a line setlocal enabledelayedexpansion after the @echo off line and then replace any %x% or %y% within your loop with !x! or !y!

(see endless articles on SO about delayedexpansion)

BTW - why are you removing the firrst 20 characters of x? Wouldn't it be easier simply not to type them in?

Sign up to request clarification or add additional context in comments.

1 Comment

Here is how this code is used - in my company, we have a lot of testing equipment running windows that I need to frequently remotely connect to. The problem is that the IP addresses of the equipment change constantly. There is a directory on a shared network drive where each of the test stations is periodically saving some metadata about itself, and the IP address is there, starting from 21st symbol. This main batch file is creating other small files that act as shortcuts to tightvnc, a remote desktop program. Your corrections worked perfectly, big thanks to you!
1

When you define a variable inside of a for loop, you need to use delayed expansion. Having the setlocal enabledelayedexpansion command is not enough; you also need to change % to !

FOR %%A in (FileOne FileTwo) DO (

set /p x=<"path were all the source files are kept\%%A.txt"
set x=!x:~20!
set y="C:\Program Files\TightVNC\tvnviewer" -password=zzz !x!
break> %%A.bat
echo !y! >>%%A.bat

)

1 Comment

Hi, your slution is also correct, but I can only mark one comment as a solution. I chose Magoo's because it had more background on why my code didn't work. Still than you for your answer!
0

You can run batch in CMD with enabled delayed environment variable expansion.

CMD /V:ON

And without setlocal enabledelayedexpansion command in file. And echo %y% >>%%A.bat must be changed to (echo %y%) >>%%A.bat to strip quotes out.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.