50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
import sys
|
|
import subprocess
|
|
import py
|
|
from subprocess import Popen, PIPE
|
|
|
|
def cmdexec(cmd):
|
|
""" return unicode output of executing 'cmd' in a separate process.
|
|
|
|
raise cmdexec.Error exeception if the command failed.
|
|
the exception will provide an 'err' attribute containing
|
|
the error-output from the command.
|
|
if the subprocess module does not provide a proper encoding/unicode strings
|
|
sys.getdefaultencoding() will be used, if that does not exist, 'UTF-8'.
|
|
"""
|
|
process = subprocess.Popen(cmd, shell=True,
|
|
universal_newlines=True,
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
out, err = process.communicate()
|
|
if sys.version_info[0] < 3: # on py3 we get unicode strings, on py2 not
|
|
try:
|
|
default_encoding = sys.getdefaultencoding() # jython may not have it
|
|
except AttributeError:
|
|
default_encoding = sys.stdout.encoding or 'UTF-8'
|
|
out = unicode(out, process.stdout.encoding or default_encoding)
|
|
err = unicode(err, process.stderr.encoding or default_encoding)
|
|
status = process.poll()
|
|
if status:
|
|
raise ExecutionFailed(status, status, cmd, out, err)
|
|
return out
|
|
|
|
class ExecutionFailed(py.error.Error):
|
|
def __init__(self, status, systemstatus, cmd, out, err):
|
|
Exception.__init__(self)
|
|
self.status = status
|
|
self.systemstatus = systemstatus
|
|
self.cmd = cmd
|
|
self.err = err
|
|
self.out = out
|
|
|
|
def __str__(self):
|
|
return "ExecutionFailed: %d %s\n%s" %(self.status, self.cmd, self.err)
|
|
|
|
# export the exception under the name 'py.process.cmdexec.Error'
|
|
cmdexec.Error = ExecutionFailed
|
|
try:
|
|
ExecutionFailed.__module__ = 'py.process.cmdexec'
|
|
ExecutionFailed.__name__ = 'Error'
|
|
except (AttributeError, TypeError):
|
|
pass
|