我有一个简单的函数,用于检查程序是否正在运行并根据需要返回一个布尔值。它通过使用模块ps -A
检查命令subprocess
的输出来完成此操作。我试图让这个函数在Python 2和Python 3中都能正常工作但遇到以下错误:
TypeError: a bytes-like object is required, not 'str'
如何更改函数,以便它可以在两个 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
编辑:在@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'
答案 0 :(得分:1)
使用b"\n"
之类的字节串而不是普通"\n"
,并使用program.encode()
代替program
(假设您正在传递字符串):< / p>
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
]
这是因为在Python 3中,subprocess.Popen.communicate
默认返回字节而不是字符串。在Python 2.6+中,b"\n" == "\n"
,所以你不应该有任何问题。
答案 1 :(得分:0)
这是一个古老的问题,但是我发现了一种更简单的方法可以在Python 2和3中使用:在.decode()
之后添加communicate()[0]
:
results = subprocess.Popen(
["ps", "-A"],
stdout = subprocess.PIPE
).communicate()[0].decode().split("\n")
因此,您不必在每个字符串文字或b
之前添加encode()
到代码中的字符串变量。另外,results
将成为Unicode字符串。
PS。就我而言,我有subprocess.check_output()
并附加了.decode()
也按预期工作。
编辑:也许最好指定编码,例如decode('utf-8')
,以防万一。
答案 2 :(得分:0)
universal_newlines=True
生成字符串而不是字节。
results = subprocess.Popen(
["ps", "-A"],
stdout = subprocess.PIPE,
universal_newlines=True
).communicate()[0].split("\n")
使用迭代器
p = subprocess.Popen(
["ps", "-A"],
stdout = subprocess.PIPE,
universal_newlines=True
)
for result in p.stdin:
print(result.strip())