-2

I'm using windows 10, running batch files through the command prompt window.

I can make things work, but I don't know why it works or why I can't do certain things:

set "file_list=a1 a2"
for %%a in (%file_list%) do (
    echo %%a.py
)

This little piece of code works. I can build on it, BUT

Q1: I want to change the variable %%a to %%filename... but that doesn't work! I wondered if maybe filename were reserved, so I tried %%fname . In this case I get the error:

%fname was unexpected at this time.

I can do a set fromm the command line and use a descriptive variable name, but it doesn't seem to work when looping. (I did it with the %file_list% variable above!) So how come I can only use a single character for a loop variable? Is there some way around that?

Q1a. This makes me think that the loop index variable is a different kind of variable that the ones in set commands. Is that correct? If so, is there a link that clearly and concisely explains the difference?

Q2. I notice the loop index variable is %%a, instead of a or %a or %a% . I never would have guessed this. The web sites I've looked at have just said, do this. But I can't see any explanation of why, except that the first percent is an escape. Okay. That doesn't really explain anything. It just means "this is how you do it." The error message when I use one percent sign is interesting.

set "file_list=a1 a2"
for %a in (%file_list%) do (
    echo %a.py
)

"file_list) was unexpected at this time."

So I can vaguely see that maybe something isn't being escaped correctly. Why does that % in the %a need to be escaped, so it becomes %%a ?

elbillaf
  • 1,774
  • 10
  • 35
  • 61
  • Somewhere close to the top of the help information for the `for` command, _(use `for /?` or `help for` at the Command Prompt)_, you should clearly see something like this `To use the FOR command in a batch program, specify %%variable instead of %variable.` – Compo Jun 04 '20 at 17:52
  • A female engineer at IBM made these decisions. And the reason is to run MSDos batch files. –  Jun 04 '20 at 18:24
  • `for` only accepts one letter arguments. Thats just how for works. – Nico Nekoru Jun 04 '20 at 19:07
  • And it is not unintuitive for MSDos users. Its been pretty much the same syntax for **39 years**. –  Jun 05 '20 at 19:40

1 Answers1

1

A for meta-variable must consist of % (in Command Prompt) or %% (in a batch file) and a single character (case-sensitive letter), like %a or %%a. You cannot define %filename or %%filename.
Loop variables only exist within the respective for loop. Do not confuse such loop variables with normal environment variables, like %TEMP%, for example, which are available globally.

There are these things marked by %-signs:

  1. %-escaping (only applicable for batch files), so %% denotes one literal %-sign;
  2. command line arguments/parameters (only applicable for batch files, obviously), like %1;
  3. immediately expanded environment variables*, like %TEMP%;
  4. for meta-variables, like %a (in Command Prompt) or %%a (in batch files), which are specific to the for command, so they do not exist outside of the related loop context;

%-escaping (1.) happens before expanding for meta-variables (4.), hence actually the for command receives a loop variable like %a.
Then environment variables (3.) are treated differently in Command Prompt and in batch files: the former keeps undefined variables literally, the latter removes them.
The detailed parsing rules can be found in this post, which have been implemented by Microsoft (or IBM?) that way in order to be able to distinguish between the different %-things, so at the end it was their decision, therefore you have to ask them for the exact reason…


*) There is also something like delayed environment variable expansion, but this uses !-signs to mark the variables, like !TEMP!, and this is something that happens after all the %-sign expressions have been parsed.

aschipfl
  • 28,946
  • 10
  • 45
  • 77