2

I'm trying to append four directories to %pythonpath%. The directories are:

  1. C:\src\tensorflow\models\research
  2. C:\src\tensorflow\models\research\object_detection
  3. ..\utils
  4. ..\mail

When user is User42, %pythonpath% is always set to:

;C:\src\tensorflow\models\research\object_detection;..\utils;..\mail

Why is the first path ignored/overwritten?

@echo off
if "%username%"=="User42" (
    set pythonpath=%pythonpath%;C:\src\tensorflow\models\research
    set pythonpath=%pythonpath%;C:\src\tensorflow\models\research\object_detection
) else (
    :: Other path
)

:: This is common to all users
set pythonpath=%pythonpath%;..\utils;..\mail
echo %pythonpath%
Turambar
  • 153
  • 11
  • 1
    Use delayedexpansion. Dupe https://stackoverflow.com/questions/9102422/windows-batch-set-inside-if-not-working and https://stackoverflow.com/questions/9681863/windows-batch-variables-wont-set and maybe https://stackoverflow.com/questions/33198978/batch-setlocal-enabledelayedexpansion-and-math-problems also https://superuser.com/questions/78496/ https://superuser.com/questions/330118/ where it is ontopic unlike here – dave_thompson_085 Aug 21 '18 at 01:44
  • Possible duplicate of [windows batch SET inside IF not working](https://stackoverflow.com/questions/9102422/windows-batch-set-inside-if-not-working) – aschipfl Aug 21 '18 at 07:43
  • Just update the variable in one shot: `set pythonpath=%pythonpath%;C:\src\tensorflow\models\research;C:\src\tensorflow\models\research\object_detection`, so there is no need for delayed expansion... – aschipfl Aug 21 '18 at 07:44

2 Answers2

1

%pythonpath% used twice between parentheses will be evaluated on read before execution begins. This is why %pythonpath% has the same value on the 2nd set.

You can use call set to force evaluation on the variable with doubled %s. This has a similar effect to enabledelayedexpansion seen in setlocal /? and if /?.

@echo off
if "%username%"=="User42" (
    set "pythonpath=%pythonpath%;C:\src\tensorflow\models\research"
    call set "pythonpath=%%pythonpath%%;C:\src\tensorflow\models\research\object_detection"
) else (
    :: Other path
)

:: This is common to all users
set "pythonpath=%pythonpath%;..\utils;..\mail"
echo %pythonpath%
michael_heath
  • 5,262
  • 2
  • 12
  • 22
1

Windows command processor replaces all environment variable references with syntax %VariableName% in a command block starting with ( and ending with matching ) during parsing phase of the next command line to execute on which a command block begins. In this case this means all %pythonpath% in both branches of the IF condition are substituted already by the current value of environment variable pythonpath before the IF condition is executed at all. This behavior can be seen by running the batch file without @echo off from within a command prompt window as in this case Windows command processor outputs the command lines after being parsed before execution.

The solution is using delayed expansion as also explained by help of command SET output on running in a command prompt window set /? on an IF and a FOR example, or avoiding the definition or modification of an environment variable and referencing it once again in same command block.

Here is a solution which works without usage of delayed expansion:

@echo off
set "Separator="
if defined pythonpath if not "%pythonpath:~-1%" == ";" set "Separator=;"
if /I "%username%" == "User42" (
    set "pythonpath=%pythonpath%%Separator%C:\src\tensorflow\models\research;C:\src\tensorflow\models\research\object_detection"
) else (
    rem Other path is added here to environment variable pythonpath.
)

rem This is common to all users. Variable pythonpath is defined definitely now.
for %%I in ("%CD%") do set "ParentPath=%%~dpI"
set "pythonpath=%pythonpath%;%ParentPath%utils;%ParentPath%mail"
echo %pythonpath%

It additionally makes sure there is not ;; in value of pythonpath in case of there is already a semicolon at end. And it makes sure pythonpath is not defined with a ; at beginning if this environment variable does not exist at all before first IF condition.

Further there are no relative paths added to pythonpath because of determining absolute path for ..\utils and ..\mails before appending them to pythonpath.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • echo /?
  • if /?
  • rem /?
  • set /?

BTW: Invalid labels :: as comments should not be used in command blocks. That can result in undefined behavior on execution. It is safer to use command REM for comments.

Mofi
  • 46,139
  • 17
  • 80
  • 143