subprocess python 3 check_output 与 shell 命令不同?

subprocess python 3 check_output not same as shell command?

我正在尝试使用 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'
  • shlex.split() 语法与 cmd.exe (%COMSPEC%)
  • 使用的语法不同
  • 对 Windows 路径使用原始字符串文字,即使用 r'c:\Users' 而不是 'c:\Users'
  • 你在这里不需要 shell=True 并且你不应该将它与列表参数一起使用
  • 您不需要在 Windows 上拆分命令:字符串是本机接口

可以使用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