subprocess.getstatusoutput(来自Python的旧命令.setstatusoutput())的多平台替代方法是什么?

sor*_*rin 9 python redirect process

下面的代码在Python 3.0中已经过时了,被替换为subprocess.getstatusoutput().

import commands
(ret, out) = commands.getstatusoutput('some command')
print ret
print out
Run Code Online (Sandbox Code Playgroud)

真正的问题是什么是来自Python的这个命令的多平台替代品,因为上面的代码确实在Windows下失败了,因为getstatusoutput仅在Unix下支持而Python不告诉你这个,而是你得到类似的东西:

>test.py
1
'{' is not recognized as an internal or external command,
operable program or batch file.
Run Code Online (Sandbox Code Playgroud)

D.S*_*ley 8

我不会真的考虑这个多平台,但你可以使用subprocess.Popen:

import subprocess
pipe = subprocess.Popen('dir', stdout=subprocess.PIPE, shell=True, universal_newlines=True)
output = pipe.stdout.readlines()
sts = pipe.wait()
print sts
print output
Run Code Online (Sandbox Code Playgroud)

以下是替代品getstatusoutput:

def getstatusoutput(cmd): 
    """Return (status, output) of executing cmd in a shell."""
    """This new implementation should work on all platforms."""
    import subprocess
    pipe = subprocess.Popen(cmd, shell=True, universal_newlines=True,
            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = str.join("", pipe.stdout.readlines()) 
    sts = pipe.wait()
    if sts is None:
        sts = 0
    return sts, output
Run Code Online (Sandbox Code Playgroud)

这个片段是由原始海报提出的.我做了,因为一些变化 getstatusoutput重复stderrstdout.


问题是,这dir不是一个多平台调用,但subprocess.Popen允许您在任何平台上执行shell命令.除非你绝对需要,否则我会避免使用shell命令.调查的内容os,os.pathshutil包来代替.

import os
import os.path
for rel_name in os.listdir(os.curdir):
  abs_name = os.path.join(os.curdir, rel_name)
  if os.path.isdir(abs_name):
    print('DIR:  ' + rel_name)
  elif os.path.isfile(abs_name):
    print('FILE: ' + rel_name)
  else:
    print('UNK?  ' + rel_name)
Run Code Online (Sandbox Code Playgroud)


sor*_*rin 8

这将是getstatusoutput()的多平台实现:

def getstatusoutput(cmd): 
    """Return (status, output) of executing cmd in a shell."""
    """This new implementation should work on all platforms."""
    import subprocess
    pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, universal_newlines=True)  
    output = "".join(pipe.stdout.readlines()) 
    sts = pipe.returncode
    if sts is None: sts = 0
    return sts, output
Run Code Online (Sandbox Code Playgroud)