【问题标题】:subprocess python 3 check_output not same as shell command?子进程 python 3 check_output 与 shell 命令不同?
【发布时间】:2015-06-23 07:56:15
【问题描述】:

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

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'

【问题讨论】:

  • 不相关:不要使用python setup.py install,而是更喜欢pip install -r requirements.txt:它可以启用正确卸载,并且可以加快重新安装(由于车轮支持)。
  • 是的,我使用 setup install 的唯一原因是因为我所在的服务器无法访问 Internet。所以我必须在本地拥有所有安装文件
  • 你可以在没有互联网的情况下使用pip
  • 嘿 J.F 是的,我正在运行 python 3.3,所以默认情况下它没有安装 pip。此外,当我尝试使用 python get-pip.py 下载 pip 时,我无法访问互联网,因此无法下载。在互联网上阅读,我可以安装 pip 的 .wheel,但不支持或不推荐。现在我很高兴使用 python 完成安装,但是如果这个项目的大小开始急剧增加,感谢您的反馈会记住它
  • AttributeError 是由于拼写错误:比较 sys.stderrsys.sterr

标签: python-3.x subprocess


【解决方案1】:
  • 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

【讨论】:

  • 感谢您的回复 J.F. 这个模块开始变得更有意义了。我遇到了 sys.stderr.buffer.write(e.output) 行的问题,我收到此错误 sys.stderr.buffer.write(e.output) AttributeError: 'PseudoOutputFile' object has no attribute 'buffer'。我不知道发生了什么
  • @JustinS:使用常规 Python 运行您的脚本。
  • 嘿,J.F 不确定您的意思是什么?我通过在 IDLE 中按“F5”来运行此脚本?
  • IDLE 替换 sys.stderr。从命令行运行脚本,例如 py your_script.py
猜你喜欢
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-21
  • 2012-06-18
相关资源
最近更新 更多