【问题标题】:Python Subprocess controlling outputPython 子进程控制输出
【发布时间】:2018-05-28 02:43:00
【问题描述】:

我有一个基础 python 项目,它可以接受其他 python 文件并将它们作为子进程执行。基础项目接受用户输入,将其提供给子流程,然后子流程执行代码并通过标准输出返回一个值,该值反馈给用户。

在基础程序中,我正在做类似的事情:

dataReturnValue = subprocess.check_output(['python', pythonScriptPath, json.dumps(inputParams)])

然后在子流程中我有这样的东西:

inputParams = sys.argv[1]
...
...
sys.stdout.write(returnValue)

数据已正确返回,但我想做的是将返回的数据限制为returnValue。现在它返回整个子流程中的所有打印语句以及返回值。这对我来说很有意义,因为它是一种输出形式,而 print 类似于 stdout 包装器,但我想更好地控制它。

有没有办法在我的最终输出语句之前清除标准输出缓冲区,以便子进程返回的值中不包含杂散打印或输出?

编辑:我尝试在最后一次调用之前执行 sys.stdout.buffer.flush()、sys.stdout.flush(),希望它能清除缓冲区,但之前的打印语句仍然出现与最终返回值一起发送。

【问题讨论】:

  • 如果是 python 脚本,也许使用subprocess 不是最好的方法。如果您致力于这种方法,也许可以考虑打印一个作为分隔符的标记值。例如print('SENTINEL',end=''),然后执行value = dataReturnValue.split('SENTINEL')[-1]——但实际上,理想情况下您只想导入脚本并调用函数。

标签: python subprocess buffer stdout


【解决方案1】:

也许这对你有帮助。

您可以使用子流程 Popen,PIPE 来完成您的任务。如果您希望使用多个子流程实例,请点击此处的链接

Python subprocess: how to use pipes thrice?

如何控制输出?

下面的命令(虚拟命令)将生成 100 行,但我只需要一行包含文本“Appium Started”的行

from subprocess import Popen,PIPE
command='appium-p 4723'
p1=Popen(command,stdout=Pipe)

return_value= 'Started Appium'

#this will store the output which command generated 
output = p3.communicate()[0]

for line in output:
    if returnvalue in line:
        print line
    else:
        pass

最后你只会得到你想要的行,即 Appium Started

【讨论】:

    【解决方案2】:

    试试这个:

    import sys
    import os
    
    # Your code here
    
    with open(os.devnull, 'w') as sys.stdout:
        # Code that you don't want to be printed here
    sys.stdout = sys.__stdout__
    
    # Your code here
    

    编辑:

    我什至把它变成了你的装饰器

    import sys
    import os
    
    def silence(func, *args, **kwargs):
        def wrapper(*args, **kwargs):
            with open(os.devnull, 'w') as sys.stdout:
                result = func(*args, **kwargs)
            sys.__dict__['stdout'] = sys.__stdout__
            return result
         return wrapper
    

    在这样的任何功能上使用它:

    def test1():
        print("TEST1")
    
    @silence
    def test2():
        print("TEST2")
    
    def test3():
        print("TEST3")
    
    test1()
    test2()
    test3()
    

    输出:

    TEST1
    TEST3
    

    【讨论】:

    • 这确实没有返回错误,但它也没有返回任何输出,因为我确实希望 stdout 可用于最后一次输出调用
    • 我还担心打开和关闭标准输出缓冲区会弄乱主进程和子进程之间传递的任何引用
    • 我对其进行了编辑以解决这个问题。让我知道这是否适合您。
    【解决方案3】:

    这可能不是您正在寻找的答案,但也许这是一种可能的解决方法:

    dataReturnValue = dataReturnValue.split("\n")[-1]

    【讨论】:

    • 这个可以作为一种解决方法,至少在简单的输出上是这样,但我担心如果我想要返回的数据确实包含一个 \n 那么它只会返回所需输出的一部分并且不是全部。它确实让我想到了一个微小的变化,也许我可以在数据输出前添加一个特定的键,我可以通过
    猜你喜欢
    • 2014-03-13
    • 2022-01-04
    • 2018-10-04
    • 2017-02-07
    • 2014-01-25
    • 2017-11-18
    • 2014-01-01
    • 1970-01-01
    • 2014-06-30
    相关资源
    最近更新 更多