我有一个简单的函数,可以检查程序是否正在运行并根据需要返回布尔值。它通过使用模块subprocess
ps -A
检查命令的输出来做到这一点。我正在尝试让这个函数在 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'
使用像 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
]
这是因为在 Python 3 中,subprocess.Popen.communicate
默认返回字节而不是字符串。在 Python 2.6+ 中,b"n" == "n"
,所以你应该没有任何问题。
这是一个老问题,但我找到了一种在 Python 2 和 3 中都适用的更简单的方法:在 communicate()[0]
后添加 .decode()
:
results = subprocess.Popen(
["ps", "-A"],
stdout = subprocess.PIPE
).communicate()[0].decode().split("n")
因此,您不必在代码中的字符串变量的每个字符串文本或encode()
之前添加 b
's。作为奖励,results
将成为Unicode字符串。
附言。就我而言,我有subprocess.check_output()
和附加.decode()
也按预期工作。
编辑:可能最好指定编码,例如以防万一decode('utf-8')
。
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())