Python 的子进程 returns 在使用 PIPE 读取非常长的输出时截断了输出
Python's sub-process returns truncated output when using PIPE to read very long outputs
我们有一个在 NodeJS 中开发的光栅化实用程序,可将 HTML 字符串转换为呈现的 HTML 页面的 Base64。我们使用它的方式是使用子进程模块 运行 实用程序,然后使用 PIPE 读取其 STDOUT。实现这个的基本代码如下:
from subprocess import run, PIPE
result = run(['capture', tmp_file.name, '--type', 'jpeg'], stdout=PIPE, stderr=PIPE, check=True)
output = result.stdout.decode('utf-8')
输出包含呈现的 HTML 页面的 Base64 字符串。由于 Base64 对于大页面来说非常大,我注意到对于某些 HTML 页面,输出是 t运行cated 并且不完整。但是,这是随机发生的,因此 Base64 一次可能对页面正确,但下一次 t运行cated。重要的是要在这里提到,我目前正在使用线程(10 个线程)同时将 HTML 转换为 Base64 图像,因此它可能在这里发挥作用。
我对此进行了详细分析,发现在幕后,subprocess.run 方法使用 _communicate 方法,而后者又使用 os.read() 方法从 PIPE 中读取。我打印了它的输出,发现它也是 t运行cated,这就是为什么 STDOUT 是 t运行cated。完全奇怪的行为。
最后,我能够通过使用文件句柄而不是 PIPE 来解决这个问题,而且效果很好。
with open(output_filename, 'w+') as out_file:
result = run(['capture', tmp_file.name, '--type', 'jpeg'], stdout=out_file, stderr=PIPE, check=True)
我很好奇为什么 PIPE 无法处理完整的输出,而且是随机的。
当您 运行 子进程时,命令在 bash 上执行。
当您使用 PIPE 作为标准输出时,内部 bash 将数据存储在临时变量中,该变量的硬限制为 128 Kb。超过 128kb 的任何内容都会被处理运行。
处理大数据的最佳方法是捕获文件中的输出。
我们有一个在 NodeJS 中开发的光栅化实用程序,可将 HTML 字符串转换为呈现的 HTML 页面的 Base64。我们使用它的方式是使用子进程模块 运行 实用程序,然后使用 PIPE 读取其 STDOUT。实现这个的基本代码如下:
from subprocess import run, PIPE
result = run(['capture', tmp_file.name, '--type', 'jpeg'], stdout=PIPE, stderr=PIPE, check=True)
output = result.stdout.decode('utf-8')
输出包含呈现的 HTML 页面的 Base64 字符串。由于 Base64 对于大页面来说非常大,我注意到对于某些 HTML 页面,输出是 t运行cated 并且不完整。但是,这是随机发生的,因此 Base64 一次可能对页面正确,但下一次 t运行cated。重要的是要在这里提到,我目前正在使用线程(10 个线程)同时将 HTML 转换为 Base64 图像,因此它可能在这里发挥作用。
我对此进行了详细分析,发现在幕后,subprocess.run 方法使用 _communicate 方法,而后者又使用 os.read() 方法从 PIPE 中读取。我打印了它的输出,发现它也是 t运行cated,这就是为什么 STDOUT 是 t运行cated。完全奇怪的行为。
最后,我能够通过使用文件句柄而不是 PIPE 来解决这个问题,而且效果很好。
with open(output_filename, 'w+') as out_file:
result = run(['capture', tmp_file.name, '--type', 'jpeg'], stdout=out_file, stderr=PIPE, check=True)
我很好奇为什么 PIPE 无法处理完整的输出,而且是随机的。
当您 运行 子进程时,命令在 bash 上执行。 当您使用 PIPE 作为标准输出时,内部 bash 将数据存储在临时变量中,该变量的硬限制为 128 Kb。超过 128kb 的任何内容都会被处理运行。
处理大数据的最佳方法是捕获文件中的输出。