[英]Start child process with subprocess.Popen and read its output while it is running
[英]Python: executing a long-running process with subprocess.Popen, killing it, and accessing to its output
我試圖以root身份(因為必須這樣做)在線程中,python中運行“長時間運行”的進程,然后將其殺死,然后訪問其輸出。
有問題的過程是“生成”,當我在終端中啟動它時,它會在stdout上輸出文本。 但是,當我運行以下代碼時,我無權訪問stderr或stdout:
% ./example.py
Waiting for output
Pgid: 13445, pid: 13445
Stopping task
Permission Error!
Calling sudo kill 13445
B
None
None
End
編碼:
#!/usr/bin/env python3
import subprocess
import threading
import time
import os
def main():
task = TaskManager()
task.launch()
time.sleep(2)
task.stop()
print(task.stdout)
print(task.stderr)
class TaskManager(threading.Thread):
def __init__(self):
super().__init__()
self.start_event = threading.Event()
self.stderr = None
self.stdout = None
self.pgid = None
self.task = None
self.start()
def run(self):
self.start_event.wait()
self.task = subprocess.Popen(["sudo", "babeld", "-d", "2", "wlp2s0"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
preexec_fn=os.setsid)
self.pgid = os.getpgid(self.task.pid)
print("Waiting for output")
self.stdout, self.stderr = self.task.communicate()
print("End")
def launch(self):
self.start_event.set()
def stop(self):
print("Pgid: %s, pid: %s" % (self.pgid, self.task.pid))
try:
print("Stopping task")
self.task.terminate()
except PermissionError:
print("Permission Error!")
print("Calling sudo kill %d" % self.pgid)
subprocess.check_call(["sudo", "kill", str(self.pgid)])
print("B")
if __name__ == '__main__':
main()
如何在有權訪問其stderr和stdout的同時正確殺死以root身份運行的進程?
謝謝,
配方很簡單:不要使用communicate
。 您可以使用以下getter來替換self.stdout
和self.stderr
類屬性:
@property
def stdout(self):
return self.task.stdout.read()
@property
def stderr(self):
return self.task.stderr.read()
順便說一句,這種方法使您有機會拒絕代碼中的線程使用。 例:
# !/usr/bin/env python3
import subprocess
import time
import os
def main():
task = TaskManager()
task.launch()
time.sleep(2)
task.stop()
print(task.stdout)
print(task.stderr)
class TaskManager:
def __init__(self):
self.pgid = None
self.task = None
@property
def stdout(self):
return self.task.stdout.read()
@property
def stderr(self):
return self.task.stderr.read()
def launch(self):
self.task = subprocess.Popen(["sudo", "babeld", "-d", "2", "wlp2s0"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
preexec_fn=os.setsid)
self.pgid = os.getpgid(self.task.pid)
print("Waiting for output")
def stop(self):
print("Pgid: %s, pid: %s" % (self.pgid, self.task.pid))
try:
print("Stopping task")
self.task.terminate()
except PermissionError:
print("Permission Error!")
print("Calling sudo kill %d" % self.pgid)
subprocess.check_call(["sudo", "kill", str(self.pgid)])
print("B")
if __name__ == '__main__':
main()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.