os.getenv is not getting new variable settings each time it is called

Asked by Justin Pinkham

I'm trying to reset System environment variables for a string of tests (one starting after another. After each test several System environment variables need to be changed before next test is run... using the following code:

from sikuli import *
import os

def exeCmd(title,cmd):
   App.open('CMD /k start \"'+title+'\" '+cmd)

exeCmd ("env1","c:\\3mhis\\tests\\system1.bat")

Var1 = os.getenv('Var1')
Var2 = os.getenv('Var2')

print Var1
print Var2

wait (10)

exeCmd ("env1","c:\\3mhis\\tests\\system2.bat")

Var1 = os.getenv('Var1')
Var2 = os.getenv('Var2')

print Var1
print Var2

System1.bat and System 2.bat each use respectively:
Setx Var1 system1a /M
Setx Var2 system1b /M
exit

Setx with /M should set System wide environment variables and os.getenv should force retrieval of these variables.
However both print statements have the same values which are for system1.
I need to use System Environment variables because each test launches external applications that utilizes them.

I am fairly new to Sikuli
Thanks in advance.

-Justin

Question information

Language:
English Edit question
Status:
Answered
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
RaiMan (raimund-hocke) said :
#1

Has nothing to do with SikuliX as such, but with Python/Jython.

SikuliX version 1.1.1 (recommended) uses Jython 2.7

previous versions use Jython 2.5.

You should run the scripts from commandline to assure a fresh Jython interpreter environment.

Revision history for this message
Justin Pinkham (jpinkham) said :
#2

Can you elaborate? I believe the issue is actually that SikuliX starts java from a cmd.exe, and by inherent reasons the cmd.exe environment is propagating the os.getenv rather than actually getting the new values because it is being run as a "sub process" within the original cmd window..

I am new but I cannot call the batch files to change the variables for this exact reason a sub process from a batch inherits the variable values of it's parent. is this what you mean by running the scripts form the commandline?
or are you stating that I should re-call SikuliX from a command line each time which is exactly what I tried to do before my alternate (which is what I posted) again because I believe sikuli is getting the variable values from the originating cmd window.

Thanks Again

Revision history for this message
RaiMan (raimund-hocke) said :
#3

I do not understand your approach.

If you want to use the system environment for propagating values, then you should stay at that level:

# runtests.cmd
... set environment
runsikulix.cmd -r script.sikuli

... set environment
runsikulix.cmd -r script1.sikuli

... and so on

Revision history for this message
Justin Pinkham (jpinkham) said :
#4

OK, so the goal here is to kick off a series of about 30 test from 1 command, walk away and check the logs when finished for any errors. I typically do this with a master batch file however for tests where the environment variables need to change between each run this does NOT work because of child processes inheriting the parents environment variables.

here is all the code of my latest test (which is what I think you recommended above)

[justin.bat]
::Setting variables
start /wait c:\temp\test1.bat
start /wait c:\SikuliX\runsikulix_exit.cmd -r c:\SikuliX\scripts\justinOtest.sikuli

start /wait c:\temp\test2.bat
start /wait c:\SikuliX\runsikulix_exit.cmd -r c:\SikuliX\scripts\justinOtest.sikuli

[test1.bat]
setx EnvironmentVar1 Test1a /M
setx EnvironmentVar2 Test1b /M
exit

[test2.bat]
setx EnvironmentVar1 Test2a /M
setx EnvironmentVar2 Test2b /M
exit

[justinOtest]
from sikuli import *
import os
import time

EnvironmentVar1 = os.getenv('EnvironmentVar1')
EnvironmentVar2 = os.getenv('EnvironmentVar2')

print (EnvironmentVar1)
print (EnvironmentVar2)

my_testLog = open('c:\\Temp\\justin.log','a')#append to SikuliAPI if fails
dts = time.strftime('%Y-%m-%d %H:%M:%S')
Product = "Justin's environment variable Test log"
el = "\n"

my_testLog.write(dts+el+Product+el+EnvironmentVar1+el+EnvironmentVar2+el)
my_testLog.close()

[justin.log]
2017-02-02 07:43:36
Justin's environment variable Test log
Test2a
Test2b
2017-02-02 07:43:44
Justin's environment variable Test log
Test2a
Test2b

The first time it ran the log produced nothing (because the environment variables didn't exist) the justin.log file was created with 0 bytes. What you see here is the info from the 2nd run after the original bat finished (which would release the inherited environment which had nothing in it.) When I manually executed again I get the new values set by the test2.bat. You can clearly see that I never see the correct values for test1.bat. My hopes were that os.getenv would pickup the values from the registry NOT the values from the parent command window.

I appreciate your quick responses and any additional information or guidance on the matter.

Revision history for this message
RaiMan (raimund-hocke) said :
#5

ok, that does not work of course, since all the steps are different processes/environments due to the start command.

You have to make a bat, that accepts the name of the script to run and possible parameters for the script and the variables to be set to the environment. This bat internally simply sets the environment and then issues the java command taken and adapted from runsikulix.cmd.

Revision history for this message
RaiMan (raimund-hocke) said :
#6

Can you help with this problem?

Provide an answer of your own, or ask Justin Pinkham for more information if necessary.

To post a message you must log in.