Reputation: 1344
I have a small function that is used to test if an executable seems to be running. It uses the command ps -A
and the subprocess
module and returns a boolean.
def running(program):
results = subprocess.Popen(
["ps", "-A"],
stdout = subprocess.PIPE
).communicate()[0].split("\n")
matches = [
line for line in results if program in line and "defunct" not in line
]
if matches:
return True
else:
return False
It works fine in Python 2, but when I try to use it in Python 3, I encounter the following error:
TypeError: a bytes-like object is required, not 'str'
It is not obvious to me how this function could be changed neatly to work in both Python 2 and 3. I would welcome guidance.
Upvotes: 2
Views: 39
Reputation: 285
I guess the problem is that communicate() returns a byte string and you are trying to do 'if program in line' where program(i suppose) is passed as a string. You can try to convert the strings in byte-strings if program.encode() in line and "defunct".encode() not in line
EDIT
You can also try to pass 'universal_newlines=True' to Popen so to open the stream in text mode and get strings in return https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate https://docs.python.org/3/library/subprocess.html#subprocess.Popen.stdout
It works both for python 2 and python 3.
Upvotes: 1
Reputation: 4633
You get this error due to fact that Python 3.X and Python 2.X treat byte strings differently, prefix your strings with b
(for bytes) and don't intermix str
with bytes
this won't work under 3.X:
import subprocess
def running(program):
results = subprocess.Popen(["ps", "-A"],stdout=subprocess.PIPE).communicate()[0].split(b"\n")
matches = [line for line in results
if program in line and b"defunct" not in line]
if matches:
return True
else:
return False
print(running(b"python33"))
If you're using a Unix system with procfs, you could abridge the whole thing with:
res = not "Zombie" in os.popen("cat /proc/`pidof %s`/status" % 'python3')
Upvotes: 1