How do I pass a string into subprocess.Popen (using the stdin argument)?

后端 未结 11 2772
半阙折子戏
半阙折子戏 2020-11-22 01:33

If I do the following:

import subprocess
from cStringIO import StringIO
subprocess.Popen([\'grep\',\'f\'],stdout=subprocess.PIPE,stdin=StringIO(\'one\\ntwo\\         


        
相关标签:
11条回答
  • 2020-11-22 02:05

    I am using python3 and found out that you need to encode your string before you can pass it into stdin:

    p = Popen(['grep', 'f'], stdout=PIPE, stdin=PIPE, stderr=PIPE)
    out, err = p.communicate(input='one\ntwo\nthree\nfour\nfive\nsix\n'.encode())
    print(out)
    
    0 讨论(0)
  • 2020-11-22 02:05

    Apparently a cStringIO.StringIO object doesn't quack close enough to a file duck to suit subprocess.Popen

    I'm afraid not. The pipe is a low-level OS concept, so it absolutely requires a file object that is represented by an OS-level file descriptor. Your workaround is the right one.

    0 讨论(0)
  • 2020-11-22 02:07

    I figured out this workaround:

    >>> p = subprocess.Popen(['grep','f'],stdout=subprocess.PIPE,stdin=subprocess.PIPE)
    >>> p.stdin.write(b'one\ntwo\nthree\nfour\nfive\nsix\n') #expects a bytes type object
    >>> p.communicate()[0]
    'four\nfive\n'
    >>> p.stdin.close()
    

    Is there a better one?

    0 讨论(0)
  • 2020-11-22 02:11

    There's a beautiful solution if you're using Python 3.4 or better. Use the input argument instead of the stdin argument, which accepts a bytes argument:

    output = subprocess.check_output(
        ["sed", "s/foo/bar/"],
        input=b"foo",
    )
    

    This works for check_output and run, but not call or check_call for some reason.

    0 讨论(0)
  • 2020-11-22 02:13
    from subprocess import Popen, PIPE
    from tempfile import SpooledTemporaryFile as tempfile
    f = tempfile()
    f.write('one\ntwo\nthree\nfour\nfive\nsix\n')
    f.seek(0)
    print Popen(['/bin/grep','f'],stdout=PIPE,stdin=f).stdout.read()
    f.close()
    
    0 讨论(0)
提交回复
热议问题