2

I have a simple batch test file test.bat with following lines:

@echo off
REM IF "%~version_info" == "" echo No version information found
echo test

When I run it I expected to get test instead I get:

The following usage of the path operator in batch-parameter
substitution is invalid: %~version_info" == "" echo No version information found


For valid formats type CALL /? or FOR /?
The syntax of the command is incorrect.

Why does batch try to interpret the comment? Or what is happening here? If I take the comment out, the script prints out test as expected.

Also the documentation doesn't mention anything of this.

Hakaishin
  • 1,715
  • 1
  • 16
  • 36
  • 1
    This is sounded so crazy I had to check : have my upvote ! – Faibbus May 02 '18 at 08:02
  • 2
    I found a note about this [here](https://stackoverflow.com/a/12408045/5823128) : `Both [:: and REM] can't really comment out the rest of the line, so a simple %~ will cause a syntax error. ` – Faibbus May 02 '18 at 08:23
  • 5
    Read this Q&A [How does the Windows Command Interpreter (CMD.EXE) parse scripts?](https://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts) –  May 02 '18 at 08:48

5 Answers5

2

I believe it's a consequence of the parsing sequence. In this case, it's a problem, but suppose you code (as I have done):

set "debug=rem"
%debug% echo some debug data

First, we replace the values in %vars%, then we interpret the line, using the first token as the command to execute. The above construct allows the command to be varied.

So there is a method to the madness...

Magoo
  • 68,705
  • 7
  • 55
  • 76
  • I see, so the idea was that it could be used as a kind of logger. Do you maybe remember where you saw this, or where you have it from? I'm curious to how old this practice is and where it comes from. – Hakaishin May 02 '18 at 09:05
  • I've no idea about the history, but I've been using that method for years. – Magoo May 02 '18 at 13:08
2

The reason for this is the sequence of batch scripts.

The very first thing that happens is the (poor1) %-sign handling, that is the normal variable (%VAR%) and the command line argument (%1, %2, etc., and %*) expansion. Commands, and therefore even rem, are recognised in a later parsing phase.

The string %~ is an invalid argument reference, because there is neither a valid modifier or a combination of such (f, d, p, n, x, s, a, t, z, $PATH:), or a numeric digit following.

Refer to this thread: How does the Windows Command Interpreter (CMD.EXE) parse scripts?


1... The % expansion is faulty in my opinion, because %~ or %VAR:=, %VAR:*=, in case variable VAR is defined, result in an error, and variable expansion like %VAR:[*]search=[replace]% or %VAR:~[position][,[length]]% becomes aborted in case VAR is not defined (so %VAR:~%STR% becomes expanded to ~text when STR is set to text).

aschipfl
  • 28,946
  • 10
  • 45
  • 77
1

It is not ignoring it.

In batch files you need to add %% and not % so it is simply warning you that the substitution is invalid. cmdline still reads comment lines and seeing as you have a valid command in it, but incorrect method, it will warn you.

By doing this, you will not get the warning:

@echo off
REM IF "%%~version_info" == "" echo No version information found
echo test
Gerhard
  • 18,114
  • 5
  • 20
  • 38
  • I figured what it is doing and how to fix it. My question is more why? This seems like insanity, why would you want to parse comments at all? – Hakaishin May 02 '18 at 08:26
  • comments are supposed to be comments, not really lines of code, commented out. it is actually a `rem`ark. If you have a valid command, it is still being read, but seeing as you have a error in your statement, you will be told. – Gerhard May 02 '18 at 08:27
1

Why batch interpret comments?

It doesn't interpret comments, but it has to parse lines, that's the problem.

First, the parser reads a line.

Then it expands all percent expressions and then it takes a look at the first token in the line.
If the first token is REM then the remaining stuff will not be interpreted anymore (redirection, delayed expansion, pipes, ampersands, ..., are all ignored)

The problem is, that the parser first expands all percent expresssions, when there is a expression like %~ then the parser throws an error message.

jeb
  • 70,992
  • 15
  • 159
  • 202
0

If you do not want to modify the commented code, you can use:

REM %= IF "%~version_info" == "" echo No version information found

Though this is slightly ugly, it will avoid interpreting the %~.

You can find more information on comments in batch in this answer

As to why this is the case, the whole batch thing sounds a bit broken.

Faibbus
  • 1,037
  • 10
  • 17
  • nope. not related to `rem` being a command. if you change to broken label `::`, it will do the exact same – Gerhard May 02 '18 at 08:31