我在Python3中有一个脚本,如果我使用subprocess.Popen.wait()
我有问题 - 我的脚本多次迭代一些Linux命令,它看起来像我的应用程序没有响应。当我使用subprocess.Popen.communicate()
时,我的应用程序会在一秒钟内正确完成其工作。
使用Linux解决此问题的正确方法是什么?
我认为解决方案必须在某个地方使用缓冲区的变量进行操作,但我在整个互联网上搜索并找不到合适的东西。可能是我不了解整个Linux的结构和操作。
我的问题可以重新表述如下:当我使用.wait()方法时到底发生了什么?这会导致失败吗?这么久等待的原因是什么?当我中止运行任务时,我会看到下一个日志:
Traceback (most recent call last):
File "./test.py", line 6, in <module>
proc.wait()
File "/usr/lib/python3.5/subprocess.py", line 1658, in wait
(pid, sts) = self._try_wait(0)
File "/usr/lib/python3.5/subprocess.py", line 1608, in _try_wait
(pid, sts) = os.waitpid(self.pid, wait_flags)
KeyboardInterrupt
我的文件看起来大概就像接下来的事情: script.py:
#!/usr/bin/python3
# -*-coding: utf-8 -*-
import subprocess
proc = subprocess.Popen(['./1.py', '1000000'], stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
proc.wait()
out = proc.stdout.read()
# out = proc.communicate()[0]
print(len(out))
1.py:
#!/usr/bin/python3
# -*-coding: utf-8 -*-
import sys
x = sys.argv[-1]
# print(x, type(x))
for i in range(int(x)):
print(i)
UPD:据我们了解,问题是缓冲区溢出。事实证明,问题的最后一个版本是,如何使用Linux在运行脚本之前将缓冲区或重定向缓冲区扩展到文件的可能性?
UPD2:我也尝试将脚本运行为:$ python3 -u ./script.py ,但不幸的是,unbufferring不能正常工作,脚本挂起。
答案 0 :(得分:1)
您的脚本正在将输出发送到其stdout
或stderr
管道。操作系统将缓冲一些数据,然后在管道填满时永久阻止该过程。假设我有一个很长的命令,比如
longwinded.py:
for i in range(100000):
print('a'*1000)
以下内容因为stdout管道填充
而挂起import sys
import subprocess as subp
p = subp.Popen([sys.executable, 'longwinded.py'], stdout=subp.PIPE,
stderr=subp.PIPE)
p.wait()
下一个没有挂起,因为communicate
将stdout和stderr管道读入内存
p = subp.Popen([sys.executable, 'longwinded.py'], stdout=subp.PIPE,
stderr=subp.PIPE)
p.communicate()
如果你不关心stdout和err是什么,你可以将它们重定向到空设备
p = subp.Popen([sys.executable, 'longwinded.py'],
stdout=open(os.devnull, 'w'),
stderr=open(os.devnull, 'w'))
p.wait()
或将它们保存到文件
p = subp.Popen([sys.executable, 'longwinded.py'],
stdout=open('mystdout', 'w'),
stderr=open('mystderr', 'w'))
p.wait()