6

new to python, i found that subprocess's check_output runs nicely on Windows but it seems to only run cmds that are in windows PATH env variable.

i can execute the following fine:

import sys
from subprocess import check_output

cmd = check_output("ipconfig", shell=True)
print(cmd.decode(sys.stdout.encoding))

and ipconfig output is displayed fine.

if i try run a specific command not in the path and try absolute path i get errors.

import sys
from subprocess import check_output

cmd = check_output("c:\\test\\test.exe", shell=True)
print(cmd.decode(sys.stdout.encoding))

Is there no way to use an absolute path reference for check_output? i was not finding any..

i even tried changing to that directory..

import sys
from subprocess import check_output
import os

os.chdir("c:\\test\\")
cmd = check_output("test.exe", shell=True)
print(cmd.decode(sys.stdout.encoding))

but i get the following error

File "C:\Python35\lib\subprocess.py", line 398, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command 'naviseccli.exe' returned non-zero exit status 1

Process finished with exit code 1
john johnson
  • 699
  • 1
  • 12
  • 34
  • 1
    Apparently you managed to execute `naviseccli.exe` just fine, but it returned with non-zero exit status, which causes the `CalledProcessError` (which is the expected behaviour of [`check_output`](https://docs.python.org/3/library/subprocess.html#subprocess.check_output)). – mkrieger1 Apr 25 '17 at 12:49
  • What errors do you get exactly when you do `check_output("c:\\test\\test.exe", shell=True)`? – mkrieger1 Apr 25 '17 at 12:50

2 Answers2

5

Popen offers a 'cwd' argument, that will execute in the defined directory:

import subprocess
cmd = subprocess.Popen('test.exe', stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd='C:/test', shell=True)

out, err = cmd.communicate()
print (out)

Using check_output:

subprocess.check_output('cd C:/windows && notepad.exe', shell=True)
Maurice Meyer
  • 17,279
  • 4
  • 30
  • 47
  • PERFECT ! thx , this got me what i wanted. i moved from .Net to python so it's such a diff world between the 2 LOL – john johnson Apr 25 '17 at 13:22
  • I would expect an absolute path to an executable to always work, no matter what the current working directory is. Is this not the case in Python? – mihca Sep 01 '21 at 08:27
  • @mihca: Full path is always the best option. – Maurice Meyer Sep 01 '21 at 08:33
  • Yes it works with absolute paths. But one has to use backslashes on Windows when combined with `subprocess.run`. Most Python API can handle forward and backward slahes (e.g. `path.exsists`), but apparently `subprocess.run` not. This was my issue. – mihca Sep 01 '21 at 08:36
  • Actually you can use forward slashes on Windows. All of the Windows API call handle them just fine. Subprocess.run works fine with forward slashes. What doesn't work is adding shell=True if your COMSPEC environment variable is set to the default cmd.exe. Powershell also accepts forward slash. – julie Mar 24 '22 at 17:11
1

Please read about the documentation of CalledProcessError.

You can examine the output by catching this exception in a try ... except block and using the exception instance's output attribute.

try:
    ... ...                       # Running the command.
except CalledProcessError as cmderr:
    print (cmderr.output)         # Example of using the output.

In this way you can examine the failed command's exit status and output. I don't know what triggered the exact error, but it's unlikely a result of using the absolute path.

Cong Ma
  • 10,692
  • 3
  • 31
  • 47