4

I'm using python 2.7.3 on a Windows 7 64-bit machine currently (also developing in Linux 32 bit, Ubuntu 12.04) and am having odd difficulties getting python to communicate with the command prompt/terminal successfully. My code looks like this:

import subprocess, logging, platform, ctypes

class someClass (object):

def runTerminalCommand:

    try:
        terminalOrCmdLineCommand = self.toString()

        process = subprocess.Popen(terminalOrCmdLineCommand, shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
        output = process.stdout.readlines()

        if len(output) < 1:
            logging.exception("{} error : {}".format(self.cmd,process.stderr.readlines()))
            raise ConfigError("cmd issue : {}".format(self.cmd))
        return output

    except ValueError as err:
        raise err
    except Exception as e:
        logging.exception("Unexpected error : " + e.message)
        raise ConfigError("unexpected error")

Now, I know that the self.toString() returned value will process correctly if I enter it manually, so I'm limiting this to an issue with how I'm sending it to the command line via the subprocess. I've read the documentation, and found that the subprocess.check_call() doesn't return anything if it encounters an error, so I'm using .Popen()

The exception I get is,

    [date & time] ERROR: Unexpected error :
    Traceback (most recent call last):
      File "C:\[...]"
        raise ConfigError("cmd issue : {}".format(self.cmd))
    "ConfigError: cmd issue : [the list self.cmd printed out]"

What I am TRYING to do, is run a command, and read the input back. But I seem to be unable to automate the call I want to run. :(

Any thoughts? (please let me know if there are any needed details I left out)

Much appreciated, in advance.

LastTigerEyes
  • 647
  • 1
  • 9
  • 21
  • 1
    your code is not valid Python: `def runTerminalCommand: ` – jfs Oct 03 '12 at 18:31
  • So I thought it might be because the child process is running in parallel to the parent process--but it's not. When I call process.wait() before assigning output a value, I get the same problem. When I try commenting out the code: "process = subprocess.Popen(terminalOrCmdLineCommand, shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)" and replacing it with, "process = subprocess.check_call(self.cmd)" it tells me one of my flags has an invalid parameter after it. Then it lists the parameters allowed, of which one is that which I used... Still sifting through API – LastTigerEyes Oct 03 '12 at 18:33

1 Answers1

12

The docs say:

Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.

You could use .communicate() as follows:

p = Popen(cmd, stdout=PIPE, stderr=PIPE)
stdout_data, stderr_data = p.communicate()
if p.returncode != 0:
    raise RuntimeError("%r failed, status code %s stdout %r stderr %r" % (
                       cmd, p.returncode, stdout_data, stderr_data))
output_lines = stdout_data.splitlines() # you could also use `keepends=True`

See other methods to get subprocess output in Python.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
  • Aha, so, this generates me consistent issue now--seems that when I run the command in powershell it's fine, but when I run it in a regular cmd prompt, it errors out--and I suspect the child shell is run in a regular cmd prompt. Also, thanks again for the useful help! – LastTigerEyes Oct 03 '12 at 20:10