简体   繁体   English

子进程python 3 check_output与shell命令不同吗?

[英]subprocess python 3 check_output not same as shell command?

I am trying to use the subprocess module in python but its a bit tricky to get working. 我试图在python中使用subprocess模块​​,但是要开始工作有点棘手。 Here's my code 这是我的代码

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())

and my output: 和我的输出:

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'

but when i try running this command normally through cmd i get the below output 但是当我尝试通过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'.

why are they different. 他们为什么不同。 I have played with this module a little bit and its really hard to get it to put input back in and to read output from its current shell. 我已经玩了一点这个模块,要让它放回输入并从其当前外壳读取输出确实非常困难。 Any help would be greatly appreciated 任何帮助将不胜感激

UPDATE: 更新:

So the below code works yay! 所以下面的代码行不行! thanks JF! 感谢JF! But I am still having issues with 但我仍然有问题

sys.sterr.flush()

my code with the sys.sterr.flush() line commented 我的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())

The error I get when i run sys.sterr.flush() is 我运行sys.sterr.flush()时遇到的错误是

    sys.sterr.flush()
AttributeError: 'module' object has no attribute 'sterr'
  • shlex.split() syntax is different from the one used by cmd.exe ( %COMSPEC% ) shlex.split()语法与cmd.exe%COMSPEC% )使用的语法不同
  • use raw-string literals for Windows paths ie, use r'c:\\Users' instead of 'c:\\Users' 为Windows路径使用原始字符串文字,即,使用r'c:\\Users'代替'c:\\Users'
  • you don't need shell=True here and you shouldn't use it with a list argument 您不需要shell=True ,也不应将其与list参数一起使用
  • you don't need to split the command on Windows: string is the native interface 您无需在Windows上拆分命令:string是本机接口

You could use cwd parameter, to run the command in the specified directory: 您可以使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM