如何在 Python 2 和 Python 3 中处理 subprocess.Popen 输出

Bla*_*ion 6 string unicode subprocess python-3.x

我有一个简单的函数来检查程序是否正在运行并根据需要返回一个布尔值。它通过ps -A使用模块检查命令的输出来做到这一点subprocess。我试图让这个函数在 Python 2 和 Python 3 中都能工作,但遇到以下错误:

TypeError: a bytes-like object is required, not 'str'
Run Code Online (Sandbox Code Playgroud)

应如何函数变化,从而它可以工作Python 2和Python 3的?

import subprocess

def running(program):
    results = subprocess.Popen(
        ["ps", "-A"],
        stdout = subprocess.PIPE
    ).communicate()[0].split("\n")
    matches_current = [
        line for line in results if program in line and "defunct" not in line
    ]
    if matches_current:
        return True
    else:
        return False
Run Code Online (Sandbox Code Playgroud)

编辑:按照@Josh 的一些指导,我已将换行符字符串分隔符更改为字节码,但是我仍然遇到类似的问题:

>>> import subprocess
>>> def running(program):
...     results = subprocess.Popen(
...         ["ps", "-A"],
...         stdout = subprocess.PIPE
...     ).communicate()[0].split(b"\n")
...     matches_current = [
...         line for line in results if program in line and "defunct" not in line
...     ]
...     if matches_current:
...         return True
...     else:
...         return False
... 
>>> running("top")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in running
  File "<stdin>", line 7, in <listcomp>
TypeError: a bytes-like object is required, not 'str'
Run Code Online (Sandbox Code Playgroud)

Jos*_*osh 3

使用字节串b"\n"而不是普通的"\n",也可以使用program.encode()而不是program(假设你正在传递一个字符串):

results = subprocess.Popen(
    ["ps", "-A"],
    stdout = subprocess.PIPE
).communicate()[0].split(b"\n")
matches_current = [
    line for line in results if program.encode() in line and b"defunct" not in line
]
Run Code Online (Sandbox Code Playgroud)

这是因为在 Python 3 中,subprocess.Popen.communicate默认返回字节而不是字符串。在 Python 2.6+ 中,,b"\n" == "\n"所以你不应该有任何问题。