python - 取消缓冲时,Unix 脚本命令会中断终端
问题描述
抱歉标题很奇怪,也许有人可以改进它。
我在 Python 子进程中使用脚本命令来取消缓冲输出命令。然后我从该过程中读取了一行,最后我打印了一些文本。这是我的代码(此文件名为script.py
):
import subprocess
import time
proc = subprocess.Popen(["script", "-q", "-c", "cat script.py", "/dev/null"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# proc = subprocess.Popen(["stdbuf", "-oL", "-eL", "cat", "script.py"],
# stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.stdout.readline()
print("printing before...")
print("printing before...")
print("printing before...")
time.sleep(2)
print("printing after...")
print("printing after...")
print("printing after...")
我得到了这种绝对奇怪的行为,以至于当子进程写入标准输出时,后续的 python 打印语句在每行之后包含几个空格,直到进程终止。这是它的截图:
据我所知,它在每行之后打印与终端中的列相同数量的空格。我认为这可能与回车有关,但我真的不知道。stdout
我完全不明白为什么这会影响 python 的输出,因为我stderr
在做Popen
.
我在 Arch linux、python 版本 3.8.6 上运行它并uname -a
输出:
Linux carbon 5.9.10-arch1-1 #1 SMP PREEMPT Sun, 22 Nov 2020 14:16:59 +0000 x86_64 GNU/Linux
如果我能提供任何其他信息,请告诉我。
解决方案
因为你的子进程stdin
仍然是一个 TTY,script
已经达到并改变了它处理 CR 和 LF 的模式。您的前 3 次打印是script
在后台运行时制作的。在睡眠期间,script
固定终端并退出。如果您等待子流程完成,问题就会消失......通常。信号有可能会script
在其自身之后无法清理并破坏您的其余会话。可能更好的选择是重定向标准输入。
proc = subprocess.Popen(["script", "-q", "-c", "cat script.py", "/dev/null"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
这都是相当冒险的。如果执行的程序写入足够的数据来填充其标准输出管道,它将挂起。如果您只想要期望在 TTY 下运行的程序的第一行,您可以使用pty.spawn
来完成这项工作。有趣的是,它的文档有一个示例script
实现。
推荐阅读
- javascript - React 如何处理条件子节点的更新?
- r - 用另一个替换一个正则表达式匹配,反之亦然
- c++ - 基于参数值的重载函数
- javascript - 如何在没有服务器脚本的情况下使用 MAILTO 发送表单内容?
- flutter - 当前小部件完成加载后如何执行方法?
- c++ - CMake - 找不到“QT”提供的包配置文件
- excel - 尝试创建独特的 Excel 自动填充模式
- python - 使用 keras 加载 mnist 时尚数据集
- vue.js - 如何在 vuetify 中使用 i18n 配置 vee-validate?
- javascript - 使用 Shadow Root 和本机 Web 组件进行页内链接