python
  • subprocess
  • stdout
  • 2012-03-30 23 views 4 likes 
    4

    我正在寻找实现调用另一个脚本并捕获其stdout的python脚本。所调用的脚本会包含一些输入和输出消息,例如获取stdout以显示包含输入的调用脚本

    print ("Line 1 of Text") 
    variable = raw_input("Input 1 :") 
    print "Line 2 of Text Input: ", vairable 
    

    我运行代码的部分是

    import subprocess 
    
    cmd='testfile.py' 
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 
    so, se = p.communicate() 
    print(so) 
    

    所发生的问题是,标准输出不打印,直到后脚本已执行。这会留下空白的提示,等待用户输入。有没有办法让被调用的脚本仍在运行时输出stdout?

    感谢,

    +0

    从这里:HTTP://计算器。COM /问题/ 230751 /如何对平齐输出的 - 蟒蛇打印 进口SYS sys.stdout.flush() – 2012-03-30 03:48:23

    +0

    哪个操作系统,你定位?这种类型的应用程序在Windows上有一些奇怪的现象 – Fuzz 2012-03-31 03:37:41

    +0

    @Fuzz脚本需要在Windows XP和7上运行 – Scavenger 2012-03-31 03:49:23

    回答

    3

    这里有两个问题。

    1. 首先,python缓冲输出到标准输出,你需要防止这种情况。您可以按照Ilia Frenkel的建议在testfile.py中插入sys.stdout.flush()的呼叫,或者您可以使用python -u执行testfile.py以及未缓冲的I/O。 (请参阅Ilia链接到的other stack overflow question。)

    2. 您需要一种方法来异步读取子进程中的数据,然后在准备好输入时打印您读取的数据,以便提示用户出现。为此,有一个asynchronous version of the subprocess module将是非常有帮助的。

    我下载的异步子进程,并重新写你的脚本中使用它,用python -u获得无缓冲I/O一起:当我运行使用python -u我拿到这个剧本

    import async_subprocess as subprocess 
    
    cmd = ['python', '-u', 'testfile.py'] 
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE) 
    so = p.asyncread() 
    print so, 
    (so, se) = p.communicate() 
    print so 
    

    以下结果:

    $ python -u script.py 
    Line 1 of Text 
    Input 1: 
    

    和脚本暂停,等待输入。这是理想的结果。

    如果我再键入的东西(例如 “你好”)我得到以下几点:

    $ python -u script.py 
    Line 1 of Text 
    Input 1:Hullo 
    Line 2 of Text Input: Hullo 
    
    +0

    谢谢!它工作正常,但是如果测试文件的内容发生变化并且有第二个输入,那么它将因通信()运行直到达到文件结尾而停止工作 – Scavenger 2012-04-02 04:02:50

    1

    你不需要捕捉到它的stdout真的,只是将孩子程序打印出它的东西和退出,而不是输出送入你的父程序,并打印它。如果你需要变量输出,只需使用一个函数。

    但无论如何,这不是你问的。

    我实际上是从另一个计算器的问题得到了这个:

    import subprocess, sys 
    cmd='testfile.py' 
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE) 
    while True: 
        out = p.stdout.read(20) 
        if out == '' and p.poll() != None: 
         break 
        if out != '': 
         sys.stdout.write(out) 
         sys.stdout.flush() 
    

    首先,它打开了你的进程:那么它不断p读取输出并打印到使用sys.stdout.write屏幕。使这一切工作的部分是sys.stdout.flush(),它将不断“清除”程序的输出。

    +0

    @ bear605我运行代码,但它不起作用。第一个打印命令没有出现,并且脚本被按键没有做任何事情。这可能是因为我在Windows上运行。 – Scavenger 2012-04-01 22:54:32

    相关问题