0

I've come across a weird issue on Windows 10 with Batch Scripts.

This code reads in a file called manifest.yaml and compares its content to another file.

set EXECUTABLE_DIR=C:\some\path
set version=qqq

set /p oldversion=<%EXECUTABLE_DIR%\%version%\manifest.yaml
echo "%oldversion%"
set /p newversion=<%EXECUTABLE_DIR%\%version%\tmp\manifest.yaml
if "%oldversion%"=="%newversion%" (
   echo "equal"
) else (
   echo "not equal"
)

This code works on its own. But if I include this into a larger batch script, the oldversion and newversion variables are empty and I cannot find reasons why.

Things I have double checked:

  1. both files exist and do have content
  2. both files are not blocked for reading (no other program is currently writing those files)
  3. oldversion and newversion are both never used or overwritten somewhere else
  4. EXECUTABLE_DIR and version both contain the correct path to the file
  5. the short script does infact work with the original file locations the large file would use

This code is included in the larger batch script inside an if block like this:

IF exist %EXECUTABLE_DIR%\%version%\ (
  REM Code goes here
)
Scorix
  • 487
  • 6
  • 20
  • Are you sure about this? As I read your file, the variables `oldversion` and `newversion` just contain the filenames, but they don't read the content of those files. – Dominique Jun 27 '22 at 08:24
  • 2
    Probably, when you put the code into a larger script, the code is in a code block. In code blocks the percent expansion doesn't work as you expect, see [Variable behaviour in Windows batch files](https://stackoverflow.com/a/25874045/463115) – jeb Jun 27 '22 at 08:32
  • @jeb the Code is infact included inside an if block. I've edited the question to include this information – Scorix Jun 27 '22 at 08:36
  • @Gerhard the yaml file content is completely unimportant, right now the complete content of the yaml file should match or not match – Scorix Jun 27 '22 at 09:13
  • 1
    Nope, you're misunderstanding that part here. :) `set /p var= – Gerhard Jun 27 '22 at 09:14
  • True, I misswrote there, the manifest.yaml is actually just a commid id in the first line, so first line is good enough – Scorix Jun 27 '22 at 09:16
  • 1
    You can drop the code block and `delayedexpansion` by: __Line 1__`if not exist "%EXECUTABLE_DIR%\%version%" echo No such path & goto :EOF` __Line 2__ `<"%EXECUTABLE_DIR%\%version%\manifest.yaml" set /p oldV=` __Line 3__ `<"%EXECUTABLE_DIR%\%version%\tmp\manifest.yaml" set /p newV=` and __Line 4__ `(echo %oldV% | findstr "%newV%") && echo equal || echo not equal` – Gerhard Jun 27 '22 at 09:27

1 Answers1

0

This error occurred because of variable behaviours in windows batch files as described here Variable behaviour in Windows batch files

Variables inside IF code blocks are evaluated before execution if referenced like so: %variable%

If variables are changed inside that IF code block, you need to reference variables with the "delayed expansion syntax" like so !variable! as well as enabling the delayed expansion as a secondary argument in setlocal enabledelayedexpansion.

This is answered here: How do SETLOCAL and ENABLEDELAYEDEXPANSION work?

aswell as a perfect explanation how the batch line parser works: How does the Windows Command Interpreter (CMD.EXE) parse scripts?

The final code should look like this:

setlocal enabledelayedexpansion
set "EXECUTABLE_DIR=C:\some\path"
set "version=qqq"
IF exist "%EXECUTABLE_DIR%\%version%\" (
  set /p oldversion=<%EXECUTABLE_DIR%\%version%\manifest.yaml
  echo "%oldversion%"
  set /p newversion=<%EXECUTABLE_DIR%\%version%\tmp\manifest.yaml
  if "!oldversion!"=="!newversion!" (
     echo "equal"
  ) else (
     echo "not equal"
  )
) ELSE echo No such directory

Thanks to @jeb on pointing in the correct direction and @Gerhard for pointing out good coding formats.

Gerhard
  • 22,678
  • 7
  • 27
  • 43
Scorix
  • 487
  • 6
  • 20