从os.system获取输出(无子进程)

时间:2013-10-29 15:02:41

标签: python stdout interactive

我正在尝试捕获和/或删除os.system()调用启动的命令的输出。该脚本将在Linux和Windows下运行。

我无法使用子进程模块,因为所述命令是交互式的(即:用户可以键入指令以触发各种操作)。因此,请不要将此主题提及为例如:

中提出的常见问题的副本
  1. Python: How to get stdout after running os.system?
  2. How to store the return value of os.system that it has printed to stdout in python?
  3. Assign output of os.system to a variable and prevent it from being displayed on the screen
  4. ...
  5. 一个解决方案可能是使子进程使用这样的“包装”程序,但这看起来相当复杂,我想保持解决方案简单(没有外部模块或1000行代码片段......),因为它不是我的脚本的主要功能。下面的线程看起来很有希望,但它们不像原始的os.system()那样工作(它们也不是那么简单......):

    1. Running an interactive command from within python
    2. Non-blocking read on a subprocess.PIPE in python
    3. http://log.ooz.ie/2013/02/interactive-subprocess-communication-in.html
    4. 另一个解决方案可能是制定一个“tee”功能,例如本机支持的功能 在Linux发行版中。我在这里找到了一个很好的实现(例如一个Tee类,它修改了sys.stdout以将文件写入文件和原始的sys.stdout):

      问题是os.system()似乎没有打印到主脚本stdout。相反,它在子shell中启动程序,我找不到检索/抑制其输出的方法......

      如果您有任何其他方法或解决方案,请让我们知道。感谢。


      有关上下文的一些细节已在下面的评论中提出并给出。主要的询问是因为当子进程似乎是明显的解决方案时,我坚持使用os.system()。

      我执行的程序称为CAST3M(http://www-cast3m.cea.fr/)。它是用于解决各种物理领域问题的有限元代码。没有GUI,因此用户通过名为GIBIANE的命令行自定义语言进行交互。传统上,您可以使用预先编写的GIBIANE数据文件提供CAST3M,也可以在没有数据文件的情况下启动程序并即时输入命令。以下是典型的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控制是真的)

2 个答案:

答案 0 :(得分:1)

=>正如Martijn Pieters所说,没有办法检索os.system()调用的stdout(因为它产生了一个子shell =一个黑盒子,我们只知道它的返回代码)。然后解决方案是让Python充当最终用户和CAST3M之间的代理(传递配置:Python是“中间人”,听取用户请求并“按原样”将其传输到CAST3M,然后捕获CAST3M答案和将其打印回用户)。为此,您必须使用子进程,线程和队列模块。如果你不介意它带来的复杂性(以及原始人机交互体验的改变),这里有一个链接的快速摘要,可能揭示有用的:

  1. Wrap subprocess' stdout/stderr
  2. Can you make a python subprocess output stdout and stderr as usual, but also capture the output as a string?
  3. Running an interactive command from within python
  4. Non-blocking read on a subprocess.PIPE in python
  5. http://log.ooz.ie/2013/02/interactive-subprocess-communication-in.html
  6. => Robᵩ通过将日志记录任务指定给“脚本”Linux工具,仅为Linux提供了一种解决方法。这允许保持“用户<> CAST3M”交互性不变(这里没有代理)。

答案 1 :(得分:0)

在Linux上,script提供了一个交互式环境,同时捕获所有用户交互:

os.system("script -c '/bin/ed /etc/passwd' /tmp/capture_file")

上述函数调用将调用密码文件中的行编辑器ed。所有用户互动都将存储在/tmp/capture_file