2

On this question, this remains unanswered:

Is there an explanation for why I can get away with using just one percent sign in a FOR loop, when executed directly from a command prompt, and not from a batch file? I know about the DOS heritage, but we can use variables from a command line now.

You can use environment variables on the command line so why is something like FOR /L %A in (1,1,5) Do Echo %A not interpreted as the %A in (1,1,5) Do Echo % environment variable on the command line as well?

Compo
  • 36,585
  • 5
  • 27
  • 39
Lewis Kelsey
  • 4,129
  • 1
  • 32
  • 42
  • there's a major difference between interactive console/batch mode. see https://stackoverflow.com/a/7970912/12861751 – ScriptKidd May 24 '20 at 11:39
  • @HackingAddict1337 so it seems that batch mode removes the var if it isn't defined in the environment block but cmd line mode doesn't. Is this behaviour in batch mode absolutely necessary or is it how it is? I know the parsing differs but the question was more asking why is that difference necessary – Lewis Kelsey May 24 '20 at 12:31
  • 1
    remember, `cmd` is based on `DOS`, which is based on `CPM`, a 8-bit technology from 1974. So the term "necessary" is relative. Microsoft tried hard to keep code backward compatible so a lot of methods nowadays considered "unnecessary" or "weird" are still used to achieve some sort of compatibiltiy. – Stephan May 24 '20 at 12:42
  • @lewis i am confused. but to answer your question. no matter in ***cmd*** or ***batch file***, the precedence is always `parameter>variable>FOR` In interactive console the parser tries to expand, but discovers that there is no variable known as `%A in (1,1,5) Do Echo %`, so is ***kept as itself*** – ScriptKidd May 24 '20 at 12:46
  • 4
    The question is based on a wrong idea. Just try this two commands at command line: 1: `set "A in (1,1,5) Do Echo =test"` 2: `FOR /L %A in (1,1,5) Do Echo %A` – MC ND May 24 '20 at 16:20
  • 1
    testA is unexpected at this time. Which Is nice to see and I expected – Lewis Kelsey May 25 '20 at 11:59
  • 1
    @HackingAddict1337 - not quite that simple - the leading `%` is preserved, and then the remainder of the line is searched for additional vars to expand. For example, if X is undefined, and Y=1, then `%X%Y%` will expand to `%X1` on the command line. But in a batch file it would expand to `Y` because `%X%` expands to an empty string, and a lone `%` is stripped. – dbenham May 27 '20 at 03:27

1 Answers1

1

I don't know the reason why the command line parsing is so different than the batch mode parsing. Probably something to do with backward compatibility with old DOS behavior.

But the command line does attempt to treat %A in (1,1,5) Do Echo % as a variable!

D:\test>FOR /L %A in (1,1,5) Do Echo %A

D:\test>Echo 1
1

D:\test>Echo 2
2

D:\test>Echo 3
3

D:\test>Echo 4
4

D:\test>Echo 5
5

D:\test>set "A in (1,1,5) Do Echo =XXXX"

D:\test>FOR /L %A in (1,1,5) Do Echo %A
XXXXA was unexpected at this time.

In the first instance the odd variable is not defined, so the FOR command succeeds. The second time the odd variable is defined, and the expansion results in an invalid command.

Command line mode does not expand an undefined variable to nothing, but rather preserves the initial % and then looks for other variables to expand afterward.

For example, if X is undefined, and Y=1, then %X%Y% will expand to %X1 on the command line. But in a batch file it will expand to Y.

The outcomes are fully predicted by the rules posted at https://stackoverflow.com/a/7970912/1012053, but it can be hard to follow.

dbenham
  • 127,446
  • 28
  • 251
  • 390