0

By some need I was forced to correct os.environ['PATH'] to be able to run dir\to\fake\python.cmd script which adds some extra parameters to the original one before execution.

Also I have two python scripts:

test1.py:

# ...
p = subprocess.call("test2.py")   # shell=True works fine
# ...

test2.py:

# ...
print "Hello from test2.py"
# ...

When I run python test1.py my "fake" python.cmd doing its stuff, refers to the original python in c:\Python25 and runs test1.py with my extra arguments. But, sadly, test2.py, script is never called. If I put shell=True as subprocess.call argument - everythin's fine, test2.py is called.

I know, Windows is trying to find python interpreter to use for the call in the real c:\Python25 working directory when shell=False is by default.

The question to you is: how can I achieve the goal without changing my code in test1.py and test2.py? Maybe virtualenv library may be very useful in this case?

Thank you very much for your help

2
  • Does subprocess.call("test2.py") work if you run test1.py with the original python? Is your wrapper called if you run subprocess.call("test2.py", shell=True)? What are file associations for *.py files on your machine? Do you want to run all python files using python.cmd? Why can't you change test1.py code to include shell=True, what are disadvantages of shell=True in this case? Commented Nov 30, 2012 at 20:06
  • Why are you using subprocess.call() to call a python script? Just import test2 in to test1 and use threading or multiprocess to dispatch a child worker if needed, or just call it directly if it all operates sequentially anyway. You are already in python code, why go back out to the OS to run other python code? Commented Nov 30, 2012 at 20:08

1 Answer 1

1

As stated in the docs:

The shell argument (which defaults to False) specifies whether to use the shell as the program to execute.

and

On Windows with shell=True, the COMSPEC environment variable specifies the default shell. The only time you need to specify shell=True on Windows is when the command you wish to execute is built into the shell (e.g. dir or copy). You do not need shell=True to run a batch file or console-based executable.

So when you call subprocess.call("test2.py"), the system tries to call test2.py as an executable, which it is not, so it fails. However, you don't capture the return value from subprocess.open to check for error conditions, so it fails silently. When you call it with shell=True, it calls the system shell with the argument test2.py, which in turn looks up the default executable for .py files on your system and then executes the file that way.

All that said though, the deeper problem here is that your code is very poorly engineered. The probability that you have a legitimate reason to dispatch a python script via the OS from another python script is vanishingly small. Rather than patching another kludgy hack over the top of what you already have, save yourself headaches in the future and refactor the system so that it does things in an easier, more sensible, more naturally integrated way.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.