Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 2.7.3 process.Popen() failures

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.

like image 270
LastTigerEyes Avatar asked Dec 15 '22 18:12

LastTigerEyes


1 Answers

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.

like image 134
jfs Avatar answered Feb 01 '23 23:02

jfs