'Popen' 对象不可迭代
'Popen' object not Iterable
我正在尝试通过 subprocess 命令将一些 ID 提取到列表中。下面是我的代码:
list1=[]
list2=[]
list1 = subprocess.Popen("pgrep -u root",stdout=subprocess.PIPE, shell = True)
for i in list1:
file1 = open(os.path.join('/proc',i,'status')).readlines()
for line in file1:
if line.startswith("Mem: "):
id = int(line.split()[5])
if line.startswith("Cpu: "):
toC = int(line.split()[8])
list2 = (id,toC)
for k in list2:
self.text.insert(INSERT,k[0])
self.text.insert(INSERT,k[1])
我得到的错误是:“Popen”对象不可迭代。
我正在创建一个列表并将 ID 提取到列表中,然后对于列表中的每个 ID,我试图获取内存和 cpu 信息。此信息再次输入到另一个空列表(list2)中。我正在遍历 list2 以显示这些信息。我哪里错了?
如果您想要通话的结果,您需要 communicate
子进程对象
proc = subprocess.Popen(['pgrep', '-u', 'root'], stdout=subprocess.PIPE)
text = proc.communicate()[0].decode('utf-8')
for i in text.splitlines():
...
Popen
对象不是进程的输出,它是代表运行子进程的对象。
如果可以,也请避免 shell=True
,因为它被广泛认为是一个安全问题,您在这里不需要它。
调用 subprocess.Popen
产生 Popen object。它没有给你一个列表,也没有给你可以迭代的东西,因为 Popen
对象是不可迭代的。
使用同一库中的更高级别的函数将输出作为字符串获取,然后对其进行解析并相应地循环会更容易。在 Python 3.5 中,您可以简单地调用 subprocess.run
:
res = subprocess.run(["pgrep", "-u", "root"], stdout=subprocess.PIPE)
这将为您提供一个 CompletedProcess
对象,您可以从中检查输出。
在 Python 3.4 或更早版本中,您可以改为使用 check_output
。
对于这种情况(您只阅读 stdout
而 stdin
/stderr
未受影响),您可能不希望 .communicate
或 .run
。在生成行时更容易处理行,而那些 API 不会这样做(它们在 returning 之前将所有内容缓冲到内存中)。
要逐行处理输出,只需更改:
for i in list1:
至:
for i in list1.stdout:
此外,Python3 上的类型有问题;要解决这个问题(并避免 shell=True
的问题)将 Popen
行更改为:
list1 = subprocess.Popen(['pgrep', '-u', 'root'], stdout=subprocess.PIPE, universal_newlines=True)
其中 universal_newlines=True
从 list1.stdout
return str
读取数据,而不是 bytes
.
我正在尝试通过 subprocess 命令将一些 ID 提取到列表中。下面是我的代码:
list1=[]
list2=[]
list1 = subprocess.Popen("pgrep -u root",stdout=subprocess.PIPE, shell = True)
for i in list1:
file1 = open(os.path.join('/proc',i,'status')).readlines()
for line in file1:
if line.startswith("Mem: "):
id = int(line.split()[5])
if line.startswith("Cpu: "):
toC = int(line.split()[8])
list2 = (id,toC)
for k in list2:
self.text.insert(INSERT,k[0])
self.text.insert(INSERT,k[1])
我得到的错误是:“Popen”对象不可迭代。 我正在创建一个列表并将 ID 提取到列表中,然后对于列表中的每个 ID,我试图获取内存和 cpu 信息。此信息再次输入到另一个空列表(list2)中。我正在遍历 list2 以显示这些信息。我哪里错了?
如果您想要通话的结果,您需要 communicate 子进程对象
proc = subprocess.Popen(['pgrep', '-u', 'root'], stdout=subprocess.PIPE)
text = proc.communicate()[0].decode('utf-8')
for i in text.splitlines():
...
Popen
对象不是进程的输出,它是代表运行子进程的对象。
如果可以,也请避免 shell=True
,因为它被广泛认为是一个安全问题,您在这里不需要它。
调用 subprocess.Popen
产生 Popen object。它没有给你一个列表,也没有给你可以迭代的东西,因为 Popen
对象是不可迭代的。
使用同一库中的更高级别的函数将输出作为字符串获取,然后对其进行解析并相应地循环会更容易。在 Python 3.5 中,您可以简单地调用 subprocess.run
:
res = subprocess.run(["pgrep", "-u", "root"], stdout=subprocess.PIPE)
这将为您提供一个 CompletedProcess
对象,您可以从中检查输出。
在 Python 3.4 或更早版本中,您可以改为使用 check_output
。
对于这种情况(您只阅读 stdout
而 stdin
/stderr
未受影响),您可能不希望 .communicate
或 .run
。在生成行时更容易处理行,而那些 API 不会这样做(它们在 returning 之前将所有内容缓冲到内存中)。
要逐行处理输出,只需更改:
for i in list1:
至:
for i in list1.stdout:
此外,Python3 上的类型有问题;要解决这个问题(并避免 shell=True
的问题)将 Popen
行更改为:
list1 = subprocess.Popen(['pgrep', '-u', 'root'], stdout=subprocess.PIPE, universal_newlines=True)
其中 universal_newlines=True
从 list1.stdout
return str
读取数据,而不是 bytes
.