我正在尝试捕获和/或删除由 os.system() 调用启动的命令的输出。该脚本将在 Linux 和 Windows 下运行。
我不能使用 subprocess 模块,因为所述命令是交互式的(即:用户可以键入指令来触发各种操作)。因此,请不要将此线程作为常见问题的副本提及,例如:
- Python:运行 os.system 后如何获取标准输出?
- 如何在 python 中存储它打印到 stdout 的 os.system 的返回值?
- 将 os.system 的输出分配给一个变量并阻止它显示在屏幕上
- ...
一种解决方案可能是让子进程与这样一个“包装”的程序一起工作,但这似乎是一项相当复杂的任务,我想保持解决方案简单(没有外部模块或 1000 行代码片段......),因为它不是我的脚本的主要功能。以下线程似乎很有希望,但它们的工作不如粗略的 os.system() (也不是那么简单......):
- 从 python 中运行交互式命令
- 在 python 中对 subprocess.PIPE 进行非阻塞读取
- http://log.ooz.ie/2013/02/interactive-subprocess-communication-in.html
另一种解决方案可能是制定一个“tee”功能,例如 Linux 发行版中本机支持的功能。例如,我在这里找到了一个很好的实现(一个修改 sys.stdout 以写入文件和原始 sys.stdout 的 Tee 类):
问题是 os.system() 似乎没有打印到主脚本标准输出。相反,它在子shell中启动程序,我找不到检索/抑制其输出的方法......
如果您有任何其他方法或解决方案,请告诉我们。谢谢。
在下面的评论中询问并给出了有关上下文的一些细节。当子进程似乎是明显的解决方案时,主要的询问与为什么我坚持使用 os.system() 有关。
我执行的程序称为 CAST3M ( http://www-cast3m.cea.fr/ )。它是一种有限元代码,用于解决物理各个领域的问题。没有 GUI,因此用户通过称为 GIBIANE 的命令行自定义语言进行交互。传统上,您可以为 CAST3M 提供预先编写的 GIBIANE 数据文件,或者在没有数据文件的情况下启动程序并即时输入命令。以下是典型的 GIBIANE 指令(它们定义了一些点,然后是一条线、一个正方形,最后是一个立方体):
OPTI 'DONN' 3 'ELEM' 'CUB8' ;
PT1 = 0. 0. 0. ;
PT2 = 1. 0. 0. ;
PT3 = 0. 1. 0. ;
PT4 = 0. 0. 1. ;
NN1 = 5 ;
DR1 = PT1 DROI NN1 PT2 ;
SF1 = DR1 TRAN NN1 PT3 ;
VL1 = SF1 VOLU 'TRAN' NN1 PT4 ;
我用 Python 制作了一个包装器,旨在在实际启动 CAST3M 之前调整它的一些功能。我需要记录这个 Python 脚本打印的内容以及 CAST3M 会话的输出。当没有交互性时,子流程会完成这项工作。当有交互性时,我被迫使用 os.system() 因为子进程与 CAST3M 的工作很差(我只需要将它交给 CAST3M,os.system() 开箱即用,但代价是IO 控制是真的)