python-3.x - Python 脚本未按预期打印输出
问题描述
我有一个非常简单的(测试)代码,我从 Linux shell 或交互模式运行,我有两种不同的行为,我无法弄清楚原因。
我以前有一个由Popen
调用生成的文件,其中每一行都是一个文件path
。这是用于生成文件的代码:
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
(顺便说一句,我最初是在尝试构建一个PIPE
,即将这个命令的输出输入到一个grep
命令中,由于我没有以任何方式成功,我决定分解问题并从文件中读取文件路径,并一个一个地处理它们。所以也许有一个常见的问题在这个过程的某个地方阻止了我)。
由于在第二步中,我什至无法通过打开文件每一行中包含的地址来打开和处理find.txt
文件,所以我只是尝试将文件行打印出来,因为可以肯定它们在那里可用:
with open('find.txt','r') as g:
for l in g.readlines():
print(l)
现在,有趣的部分:
- 如果我将上面的行粘贴到 python shell 中,一切正常,并且我得到了预期的输出
- 另一方面,如果我尝试运行
python test.py
,其中test.py
包含上述行的文件的名称在哪里,则 shell 的标准输出中不会出现任何输出。
我试过sys.stdout.flush()
无济于事。在此过程中,我还插入了一些虚拟print()
语句:所有内容都已打印,但g.readlines()
语句之后是什么。
这是我正在尝试制作的完整脚本(我实际所追求的前身,tbh)。
#!/usr/bin/env python3
import subprocess
import sys
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
print('hello')
with open('find.txt','r') as g:
print('hello?')
for l in g.readlines():
print('help me!')
print(l)
sys.stdout.flush()
输出为:
{ancis:>106> python test.py
hello
hello?
{ancis:>106>
编辑
我在 Windows 中的安装上快速尝试了相同的行(但没有调用find
,这是不可用的)python
:它按预期工作)
基于此,我尝试运行以下更简单的代码:
print('hello')
with open('find.txt','r') as g:
print('hello?')
for l in g.readlines():
print('help me!')
print(l)
sys.stdout.flush()
作为脚本,在Linux
- 这也适用于没有问题。这应该意味着我以某种方式把事情搞砸了Popen
……但是什么?
解决方案
这是一个竞争条件。您的来电
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
正在打开另一个进程并运行您的find
命令,这需要一些时间才能完全执行。Python 然后继续并在命令完全执行并生成文件之前读取文件部分。
想测试一下吗?
time.sleep(1)
在文件打开之前添加一个。
完整的测试脚本:
#!/usr/bin/env python3
import subprocess
import time
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
time.sleep(1)
with open('find.txt','r') as g:
for l in g:
print(l)
要阻止直到该过程完成,您可以使用find.communicate()
. 有了这个,如果你想要的话,你也可以选择设置一个超时。
#!/usr/bin/env python3
import subprocess
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
find.communicate()
with open('find.txt','r') as g:
for l in g:
print(l)
来源: https ://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate
推荐阅读
- python - 了解如何将 lambda 用于 panda 的 groupby.apply
- javascript - 具有可变内容高度的可折叠面板
- woocommerce - 使用 WooCommerce API 保存 ACF 字段
- c# - 使用 Contains(Text()) 的 XPath 表达式无效
- android - Android pdf文件读取权限问题一加手机
- angular - 触发调度事件时删除 Angular,ngrx 数据
- python - 从 10 反转数字模式。(模式问题)
- c# - 将值从路由传递到自定义属性
- paypal - 贝宝付款队列
- azure - 如何将特定参数传递给 Azure 资源模板?