Ответ 1
Он был введен в 2.7. Смотрите docs.
Используйте subprocess.Popen, если вы хотите:
>>> import subprocess
>>> output = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE).communicate()[0]
Я читал документацию Python о модуле подпроцесса (см. здесь), и он говорит о команде subprocess.check_output()
, которая, кажется, именно то, что мне нужно.
Однако, когда я пытаюсь использовать его, я получаю сообщение об ошибке, которого он не существует, и когда я запускаю dir(subprocess)
, он не указан.
Я запускаю Python 2.6.5, и код, который я использовал, ниже:
import subprocess
subprocess.check_output(["ls", "-l", "/dev/null"])
Кто-нибудь знает, почему это происходит?
Он был введен в 2.7. Смотрите docs.
Используйте subprocess.Popen, если вы хотите:
>>> import subprocess
>>> output = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE).communicate()[0]
IF он сильно использовал код, который вы хотите запустить, но этот код не должен поддерживаться долгосрочным (или вам нужно быстрое исправление, независимо от потенциальных головных болей в будущем) то вы можете укусить удар (ака-патч обезьяны) там, где импортируется подпроцесс...
Просто снимите код с 2.7 и вставьте его таким образом...
import subprocess
if "check_output" not in dir( subprocess ): # duck punch it in!
def f(*popenargs, **kwargs):
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
output, unused_err = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd)
return output
subprocess.check_output = f
Может потребоваться незначительное фиджирование.
Помните, хотя на вас лежит ответственность за поддержание грязных небольших резервов. Если ошибки обнаружены и исправлены в последнем python, тогда вы: a) должны заметить это и b) обновить свою версию, если хотите оставаться в безопасности. Кроме того, переопределение и определение внутренних функций - это следующий худший кошмар для парня, особенно когда следующий парень - это ВАС несколько лет подряд, и вы забыли все о том, что вы делали в прошлый раз! Вкратце: это очень редко хорошая идея.
Благодаря предложению патча обезьяны (и мои попытки потерпели неудачу - но мы потребляли вывод CalledProcessError, поэтому для патча обезьяны требуется)
нашел рабочий патч 2.6 здесь: http://pydoc.net/Python/pep8radius/0.9.0/pep8radius.shell/
"""Note: We also monkey-patch subprocess for python 2.6 to
give feature parity with later versions.
"""
try:
from subprocess import STDOUT, check_output, CalledProcessError
except ImportError: # pragma: no cover
# python 2.6 doesn't include check_output
# monkey patch it in!
import subprocess
STDOUT = subprocess.STDOUT
def check_output(*popenargs, **kwargs):
if 'stdout' in kwargs: # pragma: no cover
raise ValueError('stdout argument not allowed, '
'it will be overridden.')
process = subprocess.Popen(stdout=subprocess.PIPE,
*popenargs, **kwargs)
output, _ = process.communicate()
retcode = process.poll()
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd,
output=output)
return output
subprocess.check_output = check_output
# overwrite CalledProcessError due to `output`
# keyword not being available (in 2.6)
class CalledProcessError(Exception):
def __init__(self, returncode, cmd, output=None):
self.returncode = returncode
self.cmd = cmd
self.output = output
def __str__(self):
return "Command '%s' returned non-zero exit status %d" % (
self.cmd, self.returncode)
subprocess.CalledProcessError = CalledProcessError