Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Is there a simple way to run a Python script on Windows/Linux/OS X?

On the latter two, subprocess.Popen("/the/script.py") works, but on Windows I get the following error:

Traceback (most recent call last):
  File "test_functional.py", line 91, in test_functional
    log = tvnamerifiy(tmp)
  File "test_functional.py", line 49, in tvnamerifiy
    stdout = PIPE
  File "C:\Python26\lib\subprocess.py", line 595, in __init__
    errread, errwrite)
  File "C:\Python26\lib\subprocess.py", line 804, in _execute_child
    startupinfo)
WindowsError: [Error 193] %1 is not a valid Win32 application


monkut's comment: The use case isn't clear. Why use subprocess to run a python script? Is there something preventing you from importing the script and calling the necessary function?

I was writing a quick script to test the overall functionality of a Python-command-line tool (to test it on various platforms). Basically it had to create a bunch of files in a temp folder, run the script on this and check the files were renamed correctly.

I could have imported the script and called the function, but since it relies on sys.argv and uses sys.exit(), I would have needed to do something like..

import sys
import tvnamer
sys.argv.append("-b", "/the/folder")
try:
    tvnamer.main()
except BaseException, errormsg:
    print type(errormsg)

Also, I wanted to capture the stdout and stderr for debugging incase something went wrong.

Of course a better way would be to write the script in more unit-testable way, but the script is basically "done" and I'm doing a final batch of testing before doing a "1.0" release (after which I'm going to do a rewrite/restructure, which will be far tidier and more testable)

Basically, it was much easier to simply run the script as a process, after finding the sys.executable variable. I would have written it as a shell-script, but that wouldn't have been cross-platform. The final script can be found here

share|improve this question
2  
The use case isn't clear. Why use subprocess to run a python script? Is there something preventing you from importing the script and calling the necessary function? –  monkut May 27 '09 at 1:26
    
Had the same problem when running nodejs modules from python. subprocess.call([r'..\nodejs\npm'], shell=True) solved the problem. –  Stefan Nov 20 '12 at 14:00

7 Answers 7

up vote 34 down vote accepted

Just found sys.executable - the full path to the current Python executable, which can be used to run the script (instead of relying on the shbang, which obviously doesn't work on Windows)

import sys
import subprocess

theproc = subprocess.Popen([sys.executable, "myscript.py"])
theproc.communicate()
share|improve this answer
    
That's even more handy than my solution. –  Robbie May 26 '09 at 21:27
1  
you could use subprocess.check_call([sys.executable, "myscript.py"]) instead. –  J.F. Sebastian Nov 22 '12 at 16:44

How about this:

import sys
import subprocess

theproc = subprocess.Popen("myscript.py", shell = True)
theproc.communicate()                   # ^^^^^^^^^^^^

This tells subprocess to use the OS shell to open your script, and works on anything that you can just run in cmd.exe.

Additionally, this will search the PATH for "myscript.py" - which could be desirable.

share|improve this answer
    
I think that'll function the same, if I recall right shell=True just stops subprocess from escaping any special characters (so "mycmd > somefile.txt" redirects text to somefile.txt, rather than trying to execute a file called "mycmd > somefile.txt") –  dbr Jun 24 '09 at 14:03
2  
Here's a situation in which the two are significantly different. Suppose "myscript.py" is in the system PATH, and not in the current directory. If you use "shell = True" the script will be found on the PATH, but if you use "sys.executable" it won't. –  romkyns Jun 24 '09 at 17:31
    
Ahh I see what you mean (although the script I was trying to run was always going to be in the current directory) –  dbr Jun 24 '09 at 20:10
    
Fixed my error, by the way it works without shell = True on python3 and fails randonly on 2.7, don't know why. –  Heather Aug 24 '13 at 14:04

It looks like windows tries to run the script using its own EXE framework rather than call it like

python /the/script.py

Try,

subprocess.Popen(["python", "/the/script.py"])

Edit: "python" would need to be on your path.

share|improve this answer
    
The python.org Windows installer doesn't seem to put the "python" command in PATH, and I think it would have the .exe suffix (which would break the other platforms) –  dbr May 26 '09 at 21:38
    
ah, I guess the .exe would break things, yes.. –  viksit May 27 '09 at 7:22
    
Hm, it seems you can exclude the .exe on Windows as long as it's in PATH, but you have to manually add Python to it –  dbr May 27 '09 at 15:01
1  
So use "cmd /S /C" instead of "python" - it's always on the path and will run the script so long as the extension is registered. –  romkyns Jun 24 '09 at 1:50

Yes subprocess.Popen(cmd, ..., shell=True) works like a charm. On Windows the .py file extension is recognized, so Python is invoked to process it (on *NIX just the usual shebang). The path environment controls whether things are seen. So the first arg to Popen is just the name of the script.

subprocess.Popen(['myscript.py', 'arg1', ...], ..., shell=True)
share|improve this answer
    
shell=True # do not show the command prompt then true, if false show it –  YumYumYum Jul 15 '14 at 7:25

When you are running a python script on windows in subprocess you should use python in front of the script name. Try:

process = subprocess.Popen("python /the/script.py")
share|improve this answer

You are using a pathname separator which is platform dependent. Windows uses "\" and Unix uses "/".

share|improve this answer
    
Good point, although in the actual script that caused the error I used os.path.join() (although I should have mentioned that) –  dbr May 27 '09 at 14:44
4  
Of course the forward slash has been valid on Windows since prehistoric times and still is, so that's not a problem. –  romkyns Jun 24 '09 at 1:48
    
@romkyns not really: subprocess.call([r'..\nodejs\npm'], shell=True) works, while subprocess.call(['../nodejs/npm'], shell=True) gives '..' is not recognized as internal or external command –  Stefan Nov 20 '12 at 14:01

For example, to execute following with command prompt or BATCH file we can use this:

C:\Python27\python.exe "C:\Program files(x86)\dev_appserver.py" --host 0.0.0.0 --post 8080 "C:\blabla\"

Same thing to do with Python, we can do this:

subprocess.Popen(['C:/Python27/python.exe', 'C:\\Program files(x86)\\dev_appserver.py', '--host', '0.0.0.0', '--port', '8080', 'C:\\blabla'], shell=True)

or

subprocess.Popen(['C:/Python27/python.exe', 'C:/Program files(x86)/dev_appserver.py', '--host', '0.0.0.0', '--port', '8080', 'C:/blabla'], shell=True)
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.