How to print stdout before writing stdin using subprocess module in Python?

Discussion in 'Python' started by Sarbjit singh, Jul 23, 2012.

  1. I am writing a script in which in the external system command may sometimesrequire user input. I am not able to handle that properly. I have tried using os.popen4 and subprocess module but could not achieve the desired behavior.

    Below mentioned example would show this problem using "cp" command. ("cp" command is used to show this problem, i am calling some different exe which may similarly prompt for user response in some scenarios). In this example there are two files present on disk and when user tries to copy file1 to file2, an conformer message comes up.

    proc = subprocess.Popen("cp -i a.txt b.txt", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,) stdout_val, stderr_val = proc.communicate() print stdout_val b.txt?

    proc.communicate("y")

    Now in this example if i read only stdout/stderr and prints it, later on ifi try to write "y" or "n" based on user's input, i got an error that channel is closed. Can some one please help me on achieving this behavior in python such that i can print stdout first, then should take user input and write stdin later on.
    Sarbjit singh, Jul 23, 2012
    #1
    1. Advertising

  2. Sarbjit singh

    Peter Otten Guest

    Re: How to print stdout before writing stdin using subprocess modulein Python?

    Sarbjit singh wrote:

    > I am writing a script in which in the external system command may
    > sometimes require user input. I am not able to handle that properly. I
    > have tried using os.popen4 and subprocess module but could not achieve the
    > desired behavior.
    >
    > Below mentioned example would show this problem using "cp" command. ("cp"
    > command is used to show this problem, i am calling some different exe
    > which may similarly prompt for user response in some scenarios). In this
    > example there are two files present on disk and when user tries to copy
    > file1 to file2, an conformer message comes up.
    >
    > proc = subprocess.Popen("cp -i a.txt b.txt", shell=True,
    > stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,)
    > stdout_val, stderr_val = proc.communicate() print stdout_val b.txt?
    >
    > proc.communicate("y")
    >
    > Now in this example if i read only stdout/stderr and prints it, later on
    > if i try to write "y" or "n" based on user's input, i got an error that
    > channel is closed. Can some one please help me on achieving this behavior
    > in python such that i can print stdout first, then should take user input
    > and write stdin later on.


    I think you need something like expect:

    http://pypi.python.org/pypi/pexpect
    Peter Otten, Jul 23, 2012
    #2
    1. Advertising

  3. Sarbjit singh

    Nobody Guest

    On Mon, 23 Jul 2012 06:01:23 -0700, Sarbjit singh wrote:

    > proc = subprocess.Popen("cp -i a.txt b.txt", shell=True,
    > stdin=subprocess.PIPE, stdout=subprocess.PIPE,
    > stderr=subprocess.STDOUT,)
    > stdout_val, stderr_val = proc.communicate()
    > print stdout_val b.txt?
    >
    > proc.communicate("y")
    >
    > Now in this example if i read only stdout/stderr and prints it, later on
    > if i try to write "y" or "n" based on user's input, i got an error that
    > channel is closed. Can some one please help me on achieving this
    > behavior in python such that i can print stdout first, then should take
    > user input and write stdin later on.


    You can't use .communicate() if you want an interact with the child
    process. Any text given as an argument is sent to the child, then the
    child's stdin is closed. Then it reads the child's stdout and/or stderr
    until the child terminates.

    If you want to interact with the child, you need to write to proc.stdin
    and read from proc.stdout and/or proc.stderr. And you need to do this
    asynchronously, i.e. you either need to use non-blocking I/O or multiple
    threads, otherwise you risk deadlock. Look at the source code for the
    ..communicate() method in subprocess.py for examples (the Unix version uses
    non-blocking I/O, the Windows version uses threads).

    Even that may not be enough, as the child process may behave differently
    if std{in,out,err} are pipes rather than a tty. Typically, stdin and
    stdout are line-buffered when associated with a tty but block-buffered
    otherwise (e.g. when associated with a pipe).

    If pipes don't work, the only solution may be to run the child process on
    a pseudo-tty (pty); see the pty module or the os.openpty() function.
    Nobody, Jul 23, 2012
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Harayasu
    Replies:
    3
    Views:
    584
    moongateclimber
    Aug 21, 2003
  2. Jan Knop
    Replies:
    4
    Views:
    1,010
    Jan knob
    Nov 24, 2003
  3. Vincent Touquet
    Replies:
    1
    Views:
    573
    Adrian B.
    Sep 3, 2004
  4. asdsd sir
    Replies:
    1
    Views:
    327
    Diez B. Roggisch
    Feb 16, 2006
  5. Andreas Persson
    Replies:
    2
    Views:
    299
    Andreas Persson
    Mar 3, 2004
Loading...

Share This Page