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

后端 未结 11 3036
半阙折子戏
半阙折子戏 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 01:55

    Popen.communicate() documentation:

    Note that if you want to send data to the process’s stdin, you need to create the Popen object with stdin=PIPE. Similarly, to get anything other than None in the result tuple, you need to give stdout=PIPE and/or stderr=PIPE too.

    Replacing os.popen*

        pipe = os.popen(cmd, 'w', bufsize)
        # ==>
        pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
    

    Warning Use communicate() rather than stdin.write(), stdout.read() or stderr.read() to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.

    So your example could be written as follows:

    from subprocess import Popen, PIPE, STDOUT
    
    p = Popen(['grep', 'f'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)    
    grep_stdout = p.communicate(input=b'one\ntwo\nthree\nfour\nfive\nsix\n')[0]
    print(grep_stdout.decode())
    # -> four
    # -> five
    # ->
    

    On Python 3.5+ (3.6+ for encoding), you could use subprocess.run, to pass input as a string to an external command and get its exit status, and its output as a string back in one call:

    #!/usr/bin/env python3
    from subprocess import run, PIPE
    
    p = run(['grep', 'f'], stdout=PIPE,
            input='one\ntwo\nthree\nfour\nfive\nsix\n', encoding='ascii')
    print(p.returncode)
    # -> 0
    print(p.stdout)
    # -> four
    # -> five
    # -> 
    

提交回复
热议问题