subprocess python 3 check_output与shell命令不一样?

时间:2015-06-22 06:19:59

标签: python-3.x subprocess

我正在尝试在python中使用子进程模块,但是它的工作有点棘手。这是我的代码

import sys
import os
import subprocess
import shlex

def install_module(dir_path, command):
    c = shlex.split(command)
    os.chdir(dir_path)
    try:
        p = subprocess.check_output(c, shell=True)
    except subprocess.CalledProcessError as e:
        #print('install failed for: ' + dir_path + ' ' + command)
        print(e.output)

def main():
    install_module('D:\installed_software\python modules\kennethreitz-requests-e95e173'
                   , 'python setup.py install')
    install_module('D:\installed_software\python modules\psycopg2-2.6.1'
                   , 'python setup.py build')
    install_module('D:\installed_software\python modules\psycopg2-2.6.1'
                   , 'python setup.py install')
    install_module('D:\installed_software\python modules\pypyodbc-1.3.3\pypyodbc-1.3.3'
                   , 'python setup.py install')

if __name__ == "__main__":
    sys.exit(main())

和我的输出:

install failed for: D:\installed_software\python modules\psycopg2-2.6.1 python setup.py build
b'running build\r\nrunning build_py\r\nrunning build_ext\r\n'
install failed for: D:\installed_software\python modules\psycopg2-2.6.1 python setup.py install
b'running install\r\nrunning build\r\nrunning build_py\r\nrunning build_ext\r\n'

但是当我尝试通常通过cmd运行此命令时,我得到以下输出

D:\installed_software\python modules\psycopg2-2.6.1>python setup.py build
running build
running build_py
running build_ext
Error: pg_config executable not found.

Please add the directory containing pg_config to the PATH
or specify the full executable path with the option:

    python setup.py build_ext --pg-config /path/to/pg_config build ...

or with the pg_config option in 'setup.cfg'.

为什么他们不同。我已经玩了这个模块一点点,很难让它输入回来并从当前的shell读取输出。任何帮助将不胜感激

更新:

所以下面的代码是正常的!谢谢J.F!但我仍然遇到问题

sys.sterr.flush()

我的代码与sys.sterr.flush()行注释

import sys
import os
from subprocess import CalledProcessError, STDOUT, check_output
import shlex

import sys
import os
from subprocess import CalledProcessError, STDOUT, check_output
import shlex

def run_in_path(command, dir_path):
    #c = shlex.split(command)
    #os.chdir(dir_path)
    try:
        p = check_output(command, cwd=dir_path, stderr=STDOUT)
    except CalledProcessError as e:
        sys.stderr.write(e.output.decode("utf-8"))
        #sys.sterr.flush()
        return e.returncode
    else:
        return 0

def main():
    run_in_path('python setup.py build',
                'D:\installed_software\python modules\kennethreitz-requests-e95e173')
    run_in_path('python setup.py build',
                   'D:\installed_software\python modules\psycopg2-2.6.1')
    run_in_path('python setup.py install',
                   'D:\installed_software\python modules\psycopg2-2.6.1')
    run_in_path('python setup.py install',
                   'D:\installed_software\python modules\pypyodbc-1.3.3\pypyodbc-1.3.3')

if __name__ == "__main__":
    sys.exit(main())

运行sys.sterr.flush()时出现的错误是

    sys.sterr.flush()
AttributeError: 'module' object has no attribute 'sterr'

1 个答案:

答案 0 :(得分:1)

  • shlex.split()语法与cmd.exe使用的语法不同(%COMSPEC%
  • 对Windows路径使用原始字符串文字,即使用r'c:\Users'代替'c:\Users'
  • 此处不需要shell=True,您不应将其与列表参数一起使用
  • 您不需要在Windows上拆分命令:string是本机接口

您可以使用cwd参数在指定目录中运行命令:

#!/usr/bin/env python3
import sys
from subprocess import CalledProcessError, STDOUT, check_output

def run_in_path(command, dir_path):
    try: #NOTE: show output only if an error happens   
        ignored = check_output(command, cwd=dir_path, stderr=STDOUT) 
    except CalledProcessError as e:
        sys.stderr.buffer.write(e.output) 
        sys.stderr.buffer.flush()
        return e.returncode
    else:
        return 0