Search code examples
pythonbatch-filesubprocessipythonspyder

Running batch file with subprocess.call does not work and freezes IPython console


This is a frequent question, but reading the other threads did not solve the problem for me. I provide the full paths to make sure I have not made any path formulation errors.

import subprocess    
# create batch script
myBat = open(r'.\Test.bat','w+') # create file with writing access
myBat.write('''echo hello
pause''') # write commands to file
myBat.close()

Now I tried running it via three different ways, found them all here on SO. In each case, my IDE Spyder goes into busy mode and the console freezes. No terminal window pops up or anything, nothing happens.

subprocess.call([r'C:\\Users\\felix\\folders\\Batch_Script\\Test.bat'], shell=True)


subprocess.Popen([r'C:\\Users\\felix\\folders\\Batch_Script\Test.bat'], creationflags=subprocess.CREATE_NEW_CONSOLE)


p = subprocess.Popen("Test.bat", cwd=r"C:\\Users\\felix\\folders\\Batch_Script\\")
stdout, stderr = p.communicate()

Each were run with and without the shell=True setting, also with and without raw strings, single backslashes and so on. Can you spot why this wont work?


Solution

  • Spyder doesn't always handle standard streams correctly so it doesn't surprise me that you see no output when using subprocess.call because it normally runs in the same console. It also makes sense why it does work for you when executed in an external cmd prompt.

    Here is what you should use if you want to keep using the spyder terminal, but call up a new window for your bat script

    subprocess.call(["start", "test.bat"], shell=True)

    start Starts a separate Command Prompt window to run a specified program or command. You need shell=True because it's a cmd built-in not a program itself. You can then just pass it your bat file as normal.