【问题标题】:From a python3 script, how to I pipe a string into a bash program?从 python3 脚本中,如何将字符串通过管道传输到 bash 程序中?
【发布时间】:2015-06-06 22:06:18
【问题描述】:

作为一个例子,这是我尝试过的:

#!/usr/bin/env python3

from subprocess import Popen

message = "Lo! I am up on an ox."
Popen('less', shell=True).communicate(input=message)

作为最后一行,我也试过了:

Popen('less', stdin=message, shell=True)

我可以为所欲为:

Popen('echo "%s" | less' % message, shell=True)

有没有更pythonic的方法?

谢谢!

【问题讨论】:

    标签: python bash python-3.x pipe subprocess


    【解决方案1】:

    stdin=subprocess.PIPE(重定向孩子的标准输入)作为@hyades suggesteduniversal_newlines=True(启用文本模式)添加到您的代码中就足够了,以便将字符串传递给子进程:

    #!/usr/bin/env python
    from subprocess import Popen, PIPE
    
    message = "Lo! I am up on an ox."
    Popen(['cat'], stdin=PIPE, 
          universal_newlines=True).communicate(input=message)
    

    除非有理由,否则不要使用shell=True

    【讨论】:

    • 这个解决了字符串到字节的问题和另一个输出较大的问题(“stdin:数据中的意外EOF,......”来自子进程)。
    【解决方案2】:

    @hyades 上面的答案当然是正确的,并且取决于您想要的可能是最好的,但是您的第二个示例不起作用的原因是因为 stdin 值必须类似于文件(就像 unix)。以下也适用于我。

    with tempfile.TemporaryFile(mode="w") as f:
         f.write(message)
         f.seek(0)
         Popen("less", stdin=f) 
    

    【讨论】:

    • 您可能应该使用r+ 模式打开文件(尽管它在我的 Ubuntu 机器上工作正常)。
    【解决方案3】:
    import subprocess
    p = subprocess.Popen('less', shell=True, stdout = subprocess.PIPE, stdin = subprocess.PIPE)
    p.stdin.write('hey!!!'.encode('utf-8'))
    print(p.communicate())
    

    可以设置PIPE与进程通信

    【讨论】:

    • 这里不需要p.stdin.write()。如果 OP 语言环境使用不同的编码,utf-8 是错误的。我没有看到问题中重定向标准输出的要求。不要在针对初学者的答案中使用shell=True。 OP 可能不知道 shell=True 没有必要甚至有害,但回答子流程问题的人应该更了解
    猜你喜欢
    • 2017-04-10
    • 2015-10-05
    • 2011-08-09
    • 2016-09-20
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    相关资源
    最近更新 更多