Read/Write from/to a process

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jas

    #1

    Read/Write from/to a process

    Hi,
    I would like to start a new process and be able to read/write from/to
    it. I have tried things like...

    import subprocess as sp
    p = sp.Popen("cmd.e xe", stdout=sp.PIPE)
    p.stdin.write(" hostname\n")

    however, it doesn't seem to work. I think the cmd.exe is catching it.

    I also tried
    f = open("out.txt", "w")
    sys.stdout = f
    os.system("cmd. exe")

    ...but out.txt didn't contain any output from cmd.exe

    So, how can I create a process (in this case, cmd.exe) on Windows and
    be able to read/write from/to it?

    Thanks

  • Dennis Lee Bieber

    #2
    Re: Read/Write from/to a process

    On 24 Oct 2005 07:20:42 -0700, "jas" <codecraig@gmai l.com> declaimed the
    following in comp.lang.pytho n:
    [color=blue]
    > Hi,
    > I would like to start a new process and be able to read/write from/to
    > it. I have tried things like...
    >
    > import subprocess as sp
    > p = sp.Popen("cmd.e xe", stdout=sp.PIPE)
    > p.stdin.write(" hostname\n")
    >
    > however, it doesn't seem to work. I think the cmd.exe is catching it.[/color]

    One: you didn't read any of the "returned" output...

    Two: the output only seems to be available upon EOF, which means the
    spawned command processor has to exit first... Though you CAN read one
    character at a time, and then have to build lines and expected prompt
    strings...


    This seems to work:
    -=-=-=-=-=-=-=-=-
    import subprocess
    import os

    PROMPT = os.getcwd() + ">"

    def getLine(proc):
    ld = []
    while True:
    c = proc.stdout.rea d(1)
    if c == "\r": continue #skip Windows <cr>
    if c != "\n": ld.append(c) #save all but <lf>
    if c is None or c == "\n" or c == ">": break
    ln = "".join(ld)
    return ln

    p = subprocess.Pope n("cmd.exe", stdout=subproce ss.PIPE, stdin =
    subprocess.PIPE )

    print "**** START of captured output"
    while True:
    ln = getLine(p)
    print ln
    if ln == PROMPT: break
    print "**** END of captured output"

    p.stdin.write(" ipconfig\n")
    print "**** START of captured output"
    while True:
    ln = getLine(p)
    print ln
    if ln == PROMPT: break
    print "**** END of captured output"

    p.stdin.write(" dir\n")
    print "**** START of captured output"
    while True:
    ln = getLine(p)
    print ln
    if ln == PROMPT: break
    print "**** END of captured output"

    p.stdin.write(" exit\n")
    -=-=-=-=-=-=-=-=-=-
    E:\UserData\Den nis Lee Bieber\My Documents>pytho n script1.py
    **** START of captured output
    Microsoft Windows XP [Version 5.1.2600]
    (C) Copyright 1985-2001 Microsoft Corp.

    E:\UserData\Den nis Lee Bieber\My Documents>
    **** END of captured output
    **** START of captured output
    ipconfig

    Windows IP Configuration


    Ethernet adapter Local Area Connection:

    Connection-specific DNS Suffix . :
    IP Address. . . . . . . . . . . . : 192.168.1.100
    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    IP Address. . . . . . . . . . . . : fe80::211:11ff: fee1:f303%4
    Default Gateway . . . . . . . . . : 192.168.1.1

    Tunnel adapter Teredo Tunneling Pseudo-Interface:

    Connection-specific DNS Suffix . :
    IP Address. . . . . . . . . . . . :
    3ffe:831f:4004: 1956:0:fbde:bd0 a:e50b
    IP Address. . . . . . . . . . . . : fe80::5445:5245 :444f%5
    Default Gateway . . . . . . . . . : ::

    Tunnel adapter Automatic Tunneling Pseudo-Interface:

    Connection-specific DNS Suffix . :
    IP Address. . . . . . . . . . . . : fe80::5efe:192. 168.1.100%2
    Default Gateway . . . . . . . . . :

    E:\UserData\Den nis Lee Bieber\My Documents>
    **** END of captured output
    **** START of captured output
    dir
    Volume in drive E is Data
    Volume Serial Number is 2626-D991

    Directory of E:\UserData\Den nis Lee Bieber\My Documents

    10/24/2005 09:23 AM <DIR>

    Comment

    • jas

      #3
      Re: Read/Write from/to a process

      Thanks, that is certainly a start. As you mentioned, the "cd" could is
      an issue.

      Perhaps checking to see if the line ends with ">" is sufficient?

      Dennis Lee Bieber wrote:[color=blue]
      > On 24 Oct 2005 07:20:42 -0700, "jas" <codecraig@gmai l.com> declaimed the
      > following in comp.lang.pytho n:
      >[color=green]
      > > Hi,
      > > I would like to start a new process and be able to read/write from/to
      > > it. I have tried things like...
      > >
      > > import subprocess as sp
      > > p = sp.Popen("cmd.e xe", stdout=sp.PIPE)
      > > p.stdin.write(" hostname\n")
      > >
      > > however, it doesn't seem to work. I think the cmd.exe is catching it.[/color]
      >
      > One: you didn't read any of the "returned" output...
      >
      > Two: the output only seems to be available upon EOF, which means the
      > spawned command processor has to exit first... Though you CAN read one
      > character at a time, and then have to build lines and expected prompt
      > strings...
      >
      >
      > This seems to work:
      > -=-=-=-=-=-=-=-=-
      > import subprocess
      > import os
      >
      > PROMPT = os.getcwd() + ">"
      >
      > def getLine(proc):
      > ld = []
      > while True:
      > c = proc.stdout.rea d(1)
      > if c == "\r": continue #skip Windows <cr>
      > if c != "\n": ld.append(c) #save all but <lf>
      > if c is None or c == "\n" or c == ">": break
      > ln = "".join(ld)
      > return ln
      >
      > p = subprocess.Pope n("cmd.exe", stdout=subproce ss.PIPE, stdin =
      > subprocess.PIPE )
      >
      > print "**** START of captured output"
      > while True:
      > ln = getLine(p)
      > print ln
      > if ln == PROMPT: break
      > print "**** END of captured output"
      >
      > p.stdin.write(" ipconfig\n")
      > print "**** START of captured output"
      > while True:
      > ln = getLine(p)
      > print ln
      > if ln == PROMPT: break
      > print "**** END of captured output"
      >
      > p.stdin.write(" dir\n")
      > print "**** START of captured output"
      > while True:
      > ln = getLine(p)
      > print ln
      > if ln == PROMPT: break
      > print "**** END of captured output"
      >
      > p.stdin.write(" exit\n")
      > -=-=-=-=-=-=-=-=-=-
      > E:\UserData\Den nis Lee Bieber\My Documents>pytho n script1.py
      > **** START of captured output
      > Microsoft Windows XP [Version 5.1.2600]
      > (C) Copyright 1985-2001 Microsoft Corp.
      >
      > E:\UserData\Den nis Lee Bieber\My Documents>
      > **** END of captured output
      > **** START of captured output
      > ipconfig
      >
      > Windows IP Configuration
      >
      >
      > Ethernet adapter Local Area Connection:
      >
      > Connection-specific DNS Suffix . :
      > IP Address. . . . . . . . . . . . : 192.168.1.100
      > Subnet Mask . . . . . . . . . . . : 255.255.255.0
      > IP Address. . . . . . . . . . . . : fe80::211:11ff: fee1:f303%4
      > Default Gateway . . . . . . . . . : 192.168.1.1
      >
      > Tunnel adapter Teredo Tunneling Pseudo-Interface:
      >
      > Connection-specific DNS Suffix . :
      > IP Address. . . . . . . . . . . . :
      > 3ffe:831f:4004: 1956:0:fbde:bd0 a:e50b
      > IP Address. . . . . . . . . . . . : fe80::5445:5245 :444f%5
      > Default Gateway . . . . . . . . . : ::
      >
      > Tunnel adapter Automatic Tunneling Pseudo-Interface:
      >
      > Connection-specific DNS Suffix . :
      > IP Address. . . . . . . . . . . . : fe80::5efe:192. 168.1.100%2
      > Default Gateway . . . . . . . . . :
      >
      > E:\UserData\Den nis Lee Bieber\My Documents>
      > **** END of captured output
      > **** START of captured output
      > dir
      > Volume in drive E is Data
      > Volume Serial Number is 2626-D991
      >
      > Directory of E:\UserData\Den nis Lee Bieber\My Documents
      >
      > 10/24/2005 09:23 AM <DIR>
      > .
      > 10/24/2005 09:23 AM <DIR>
      > ..
      > 07/25/2005 10:39 PM <DIR>
      > .metadata
      > 10/06/2005 09:54 AM <DIR>
      > Ada Progs
      > 08/13/2005 02:01 PM <DIR>
      > Agent Data
      > 10/21/2005 09:29 AM 421,820 apress_offer.pd f
      > 07/03/2005 11:36 AM 132 cp.py
      > 07/17/2005 12:25 PM <DIR>
      > Cyberlink
      > 07/06/2005 09:32 AM 102,400 db1.mdb
      > 07/26/2005 12:20 AM 26,614 eclipse_code.xm l
      > 10/24/2005 01:08 AM <DIR>
      > Eudora
      > 06/24/2005 08:50 PM 667 fake_oosums.ads
      > 06/24/2005 08:50 PM 695 fake_oosums.ali
      > 09/06/2005 09:01 PM <DIR>
      > Genealogy
      > 07/13/2005 10:56 PM <DIR>
      > HomeSite
      > 05/08/2005 01:05 PM <DIR>
      > Investing
      > 10/21/2005 10:04 PM <DIR>
      > Java Progs
      > 08/04/2005 10:13 PM 162 main.py
      > 10/11/2005 10:43 PM <DIR>
      > My Downloads
      > 05/01/2005 10:31 AM <DIR>
      > My eBooks
      > 04/22/2005 12:09 AM <DIR>
      > My Music
      > 07/10/2005 11:43 AM <DIR>
      > My Pictures
      > 06/29/2005 11:55 PM <DIR>
      > My PSP Files
      > 05/23/2005 09:30 AM <DIR>
      > My Videos
      > 05/01/2005 12:49 PM <DIR>
      > Office Documents
      > 06/27/2005 03:19 PM 7,961,778
      > org.eclipse.jdt .doc.user.I2005 0627-1435.pdf
      > 06/27/2005 03:19 PM 6,791,109
      > org.eclipse.pla tform.doc.user. I20050627-1435.pdf
      > 10/11/2005 10:52 PM 56 oth_tsr_rm_750. ram
      > 07/20/2005 09:32 AM 108,457 parkerred15yc.j pg
      > 09/03/2005 10:36 PM <DIR>
      > Python Progs
      > 10/20/2005 10:38 PM <DIR>
      > Quicken
      > 07/10/2005 12:09 PM 3,356,248 results.xml
      > 06/11/2005 12:03 PM 935 Scout_Ship Database.lnk
      > 07/03/2005 12:38 PM <DIR>
      > Scout_Ship My Documents
      > 10/24/2005 09:23 AM 971 Script1.py
      > 09/25/2005 12:40 PM 1,107 Script1_old.py
      > 08/28/2005 11:47 AM <DIR>
      > SimpleMu Logs
      > 06/24/2005 08:56 PM 1,201 student_pack.ad s
      > 06/24/2005 08:49 PM 1,144 student_pack.ad s.0
      > 06/24/2005 08:56 PM 1,342 student_pack.al i
      > 08/02/2005 11:39 PM 4,096 t.DOC
      > 06/20/2005 10:11 AM 104 t.rx
      > 08/05/2005 08:41 PM 66,452 Untitled-1.tif
      > 08/05/2005 08:41 PM <DIR>
      > VCheck
      > 10/03/2005 02:58 AM <DIR>
      > Visual Studio
      > 10/03/2005 02:51 AM <DIR>
      > Visual Studio 2005
      > 21 File(s) 18,847,490 bytes
      > 25 Dir(s) 267,162,845,184 bytes free
      >
      > E:\UserData\Den nis Lee Bieber\My Documents>
      > **** END of captured output
      >
      > E:\UserData\Den nis Lee Bieber\My Documents>
      >
      > -=-=-=-=-=-=-=-=-
      >
      > Note that my "getLine()" has to return on either a real EOL, OR on
      > the end of a command prompt ("stuff>"). I also had to initialize the
      > prompt at the start. If someone issued a "cd" command to the subprocess,
      > the prompt would be all out of sequence, and the code would hang.
      >
      > You'll also note that the prompt /ends/ a capture sequence, and the
      > next command is the start of the /next/ capture sequence.
      >
      > --[color=green]
      > > =============== =============== =============== =============== == <
      > > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
      > > wulfraed@dm.net | Bestiaria Support Staff <
      > > =============== =============== =============== =============== == <
      > > Home Page: <http://www.dm.net/~wulfraed/> <
      > > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color][/color]

      Comment

      • jas

        #4
        Re: Read/Write from/to a process

        actually, i can't check for ">" only because if you a dir, a line can
        end with a > but is not the end of the output

        jas wrote:[color=blue]
        > Thanks, that is certainly a start. As you mentioned, the "cd" could is
        > an issue.
        >
        > Perhaps checking to see if the line ends with ">" is sufficient?
        >
        > Dennis Lee Bieber wrote:[color=green]
        > > On 24 Oct 2005 07:20:42 -0700, "jas" <codecraig@gmai l.com> declaimed the
        > > following in comp.lang.pytho n:
        > >[color=darkred]
        > > > Hi,
        > > > I would like to start a new process and be able to read/write from/to
        > > > it. I have tried things like...
        > > >
        > > > import subprocess as sp
        > > > p = sp.Popen("cmd.e xe", stdout=sp.PIPE)
        > > > p.stdin.write(" hostname\n")
        > > >
        > > > however, it doesn't seem to work. I think the cmd.exe is catching it.[/color]
        > >
        > > One: you didn't read any of the "returned" output...
        > >
        > > Two: the output only seems to be available upon EOF, which means the
        > > spawned command processor has to exit first... Though you CAN read one
        > > character at a time, and then have to build lines and expected prompt
        > > strings...
        > >
        > >
        > > This seems to work:
        > > -=-=-=-=-=-=-=-=-
        > > import subprocess
        > > import os
        > >
        > > PROMPT = os.getcwd() + ">"
        > >
        > > def getLine(proc):
        > > ld = []
        > > while True:
        > > c = proc.stdout.rea d(1)
        > > if c == "\r": continue #skip Windows <cr>
        > > if c != "\n": ld.append(c) #save all but <lf>
        > > if c is None or c == "\n" or c == ">": break
        > > ln = "".join(ld)
        > > return ln
        > >
        > > p = subprocess.Pope n("cmd.exe", stdout=subproce ss.PIPE, stdin =
        > > subprocess.PIPE )
        > >
        > > print "**** START of captured output"
        > > while True:
        > > ln = getLine(p)
        > > print ln
        > > if ln == PROMPT: break
        > > print "**** END of captured output"
        > >
        > > p.stdin.write(" ipconfig\n")
        > > print "**** START of captured output"
        > > while True:
        > > ln = getLine(p)
        > > print ln
        > > if ln == PROMPT: break
        > > print "**** END of captured output"
        > >
        > > p.stdin.write(" dir\n")
        > > print "**** START of captured output"
        > > while True:
        > > ln = getLine(p)
        > > print ln
        > > if ln == PROMPT: break
        > > print "**** END of captured output"
        > >
        > > p.stdin.write(" exit\n")
        > > -=-=-=-=-=-=-=-=-=-
        > > E:\UserData\Den nis Lee Bieber\My Documents>pytho n script1.py
        > > **** START of captured output
        > > Microsoft Windows XP [Version 5.1.2600]
        > > (C) Copyright 1985-2001 Microsoft Corp.
        > >
        > > E:\UserData\Den nis Lee Bieber\My Documents>
        > > **** END of captured output
        > > **** START of captured output
        > > ipconfig
        > >
        > > Windows IP Configuration
        > >
        > >
        > > Ethernet adapter Local Area Connection:
        > >
        > > Connection-specific DNS Suffix . :
        > > IP Address. . . . . . . . . . . . : 192.168.1.100
        > > Subnet Mask . . . . . . . . . . . : 255.255.255.0
        > > IP Address. . . . . . . . . . . . : fe80::211:11ff: fee1:f303%4
        > > Default Gateway . . . . . . . . . : 192.168.1.1
        > >
        > > Tunnel adapter Teredo Tunneling Pseudo-Interface:
        > >
        > > Connection-specific DNS Suffix . :
        > > IP Address. . . . . . . . . . . . :
        > > 3ffe:831f:4004: 1956:0:fbde:bd0 a:e50b
        > > IP Address. . . . . . . . . . . . : fe80::5445:5245 :444f%5
        > > Default Gateway . . . . . . . . . : ::
        > >
        > > Tunnel adapter Automatic Tunneling Pseudo-Interface:
        > >
        > > Connection-specific DNS Suffix . :
        > > IP Address. . . . . . . . . . . . : fe80::5efe:192. 168.1.100%2
        > > Default Gateway . . . . . . . . . :
        > >
        > > E:\UserData\Den nis Lee Bieber\My Documents>
        > > **** END of captured output
        > > **** START of captured output
        > > dir
        > > Volume in drive E is Data
        > > Volume Serial Number is 2626-D991
        > >
        > > Directory of E:\UserData\Den nis Lee Bieber\My Documents
        > >
        > > 10/24/2005 09:23 AM <DIR>
        > > .
        > > 10/24/2005 09:23 AM <DIR>
        > > ..
        > > 07/25/2005 10:39 PM <DIR>
        > > .metadata
        > > 10/06/2005 09:54 AM <DIR>
        > > Ada Progs
        > > 08/13/2005 02:01 PM <DIR>
        > > Agent Data
        > > 10/21/2005 09:29 AM 421,820 apress_offer.pd f
        > > 07/03/2005 11:36 AM 132 cp.py
        > > 07/17/2005 12:25 PM <DIR>
        > > Cyberlink
        > > 07/06/2005 09:32 AM 102,400 db1.mdb
        > > 07/26/2005 12:20 AM 26,614 eclipse_code.xm l
        > > 10/24/2005 01:08 AM <DIR>
        > > Eudora
        > > 06/24/2005 08:50 PM 667 fake_oosums.ads
        > > 06/24/2005 08:50 PM 695 fake_oosums.ali
        > > 09/06/2005 09:01 PM <DIR>
        > > Genealogy
        > > 07/13/2005 10:56 PM <DIR>
        > > HomeSite
        > > 05/08/2005 01:05 PM <DIR>
        > > Investing
        > > 10/21/2005 10:04 PM <DIR>
        > > Java Progs
        > > 08/04/2005 10:13 PM 162 main.py
        > > 10/11/2005 10:43 PM <DIR>
        > > My Downloads
        > > 05/01/2005 10:31 AM <DIR>
        > > My eBooks
        > > 04/22/2005 12:09 AM <DIR>
        > > My Music
        > > 07/10/2005 11:43 AM <DIR>
        > > My Pictures
        > > 06/29/2005 11:55 PM <DIR>
        > > My PSP Files
        > > 05/23/2005 09:30 AM <DIR>
        > > My Videos
        > > 05/01/2005 12:49 PM <DIR>
        > > Office Documents
        > > 06/27/2005 03:19 PM 7,961,778
        > > org.eclipse.jdt .doc.user.I2005 0627-1435.pdf
        > > 06/27/2005 03:19 PM 6,791,109
        > > org.eclipse.pla tform.doc.user. I20050627-1435.pdf
        > > 10/11/2005 10:52 PM 56 oth_tsr_rm_750. ram
        > > 07/20/2005 09:32 AM 108,457 parkerred15yc.j pg
        > > 09/03/2005 10:36 PM <DIR>
        > > Python Progs
        > > 10/20/2005 10:38 PM <DIR>
        > > Quicken
        > > 07/10/2005 12:09 PM 3,356,248 results.xml
        > > 06/11/2005 12:03 PM 935 Scout_Ship Database.lnk
        > > 07/03/2005 12:38 PM <DIR>
        > > Scout_Ship My Documents
        > > 10/24/2005 09:23 AM 971 Script1.py
        > > 09/25/2005 12:40 PM 1,107 Script1_old.py
        > > 08/28/2005 11:47 AM <DIR>
        > > SimpleMu Logs
        > > 06/24/2005 08:56 PM 1,201 student_pack.ad s
        > > 06/24/2005 08:49 PM 1,144 student_pack.ad s.0
        > > 06/24/2005 08:56 PM 1,342 student_pack.al i
        > > 08/02/2005 11:39 PM 4,096 t.DOC
        > > 06/20/2005 10:11 AM 104 t.rx
        > > 08/05/2005 08:41 PM 66,452 Untitled-1.tif
        > > 08/05/2005 08:41 PM <DIR>
        > > VCheck
        > > 10/03/2005 02:58 AM <DIR>
        > > Visual Studio
        > > 10/03/2005 02:51 AM <DIR>
        > > Visual Studio 2005
        > > 21 File(s) 18,847,490 bytes
        > > 25 Dir(s) 267,162,845,184 bytes free
        > >
        > > E:\UserData\Den nis Lee Bieber\My Documents>
        > > **** END of captured output
        > >
        > > E:\UserData\Den nis Lee Bieber\My Documents>
        > >
        > > -=-=-=-=-=-=-=-=-
        > >
        > > Note that my "getLine()" has to return on either a real EOL, OR on
        > > the end of a command prompt ("stuff>"). I also had to initialize the
        > > prompt at the start. If someone issued a "cd" command to the subprocess,
        > > the prompt would be all out of sequence, and the code would hang.
        > >
        > > You'll also note that the prompt /ends/ a capture sequence, and the
        > > next command is the start of the /next/ capture sequence.
        > >
        > > --[color=darkred]
        > > > =============== =============== =============== =============== == <
        > > > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
        > > > wulfraed@dm.net | Bestiaria Support Staff <
        > > > =============== =============== =============== =============== == <
        > > > Home Page: <http://www.dm.net/~wulfraed/> <
        > > > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color][/color][/color]

        Comment

        • jas

          #5
          Re: Read/Write from/to a process

          What about having a thread which reads from subprocess.Pope n()'s
          stdout...instea d of read/write, read/write. just always read, and
          write when needed?

          any comments on that idea?

          jas wrote:[color=blue]
          > actually, i can't check for ">" only because if you a dir, a line can
          > end with a > but is not the end of the output
          >
          > jas wrote:[color=green]
          > > Thanks, that is certainly a start. As you mentioned, the "cd" could is
          > > an issue.
          > >
          > > Perhaps checking to see if the line ends with ">" is sufficient?
          > >
          > > Dennis Lee Bieber wrote:[color=darkred]
          > > > On 24 Oct 2005 07:20:42 -0700, "jas" <codecraig@gmai l.com> declaimed the
          > > > following in comp.lang.pytho n:
          > > >
          > > > > Hi,
          > > > > I would like to start a new process and be able to read/write from/to
          > > > > it. I have tried things like...
          > > > >
          > > > > import subprocess as sp
          > > > > p = sp.Popen("cmd.e xe", stdout=sp.PIPE)
          > > > > p.stdin.write(" hostname\n")
          > > > >
          > > > > however, it doesn't seem to work. I think the cmd.exe is catching it.
          > > >
          > > > One: you didn't read any of the "returned" output...
          > > >
          > > > Two: the output only seems to be available upon EOF, which means the
          > > > spawned command processor has to exit first... Though you CAN read one
          > > > character at a time, and then have to build lines and expected prompt
          > > > strings...
          > > >
          > > >
          > > > This seems to work:
          > > > -=-=-=-=-=-=-=-=-
          > > > import subprocess
          > > > import os
          > > >
          > > > PROMPT = os.getcwd() + ">"
          > > >
          > > > def getLine(proc):
          > > > ld = []
          > > > while True:
          > > > c = proc.stdout.rea d(1)
          > > > if c == "\r": continue #skip Windows <cr>
          > > > if c != "\n": ld.append(c) #save all but <lf>
          > > > if c is None or c == "\n" or c == ">": break
          > > > ln = "".join(ld)
          > > > return ln
          > > >
          > > > p = subprocess.Pope n("cmd.exe", stdout=subproce ss.PIPE, stdin =
          > > > subprocess.PIPE )
          > > >
          > > > print "**** START of captured output"
          > > > while True:
          > > > ln = getLine(p)
          > > > print ln
          > > > if ln == PROMPT: break
          > > > print "**** END of captured output"
          > > >
          > > > p.stdin.write(" ipconfig\n")
          > > > print "**** START of captured output"
          > > > while True:
          > > > ln = getLine(p)
          > > > print ln
          > > > if ln == PROMPT: break
          > > > print "**** END of captured output"
          > > >
          > > > p.stdin.write(" dir\n")
          > > > print "**** START of captured output"
          > > > while True:
          > > > ln = getLine(p)
          > > > print ln
          > > > if ln == PROMPT: break
          > > > print "**** END of captured output"
          > > >
          > > > p.stdin.write(" exit\n")
          > > > -=-=-=-=-=-=-=-=-=-
          > > > E:\UserData\Den nis Lee Bieber\My Documents>pytho n script1.py
          > > > **** START of captured output
          > > > Microsoft Windows XP [Version 5.1.2600]
          > > > (C) Copyright 1985-2001 Microsoft Corp.
          > > >
          > > > E:\UserData\Den nis Lee Bieber\My Documents>
          > > > **** END of captured output
          > > > **** START of captured output
          > > > ipconfig
          > > >
          > > > Windows IP Configuration
          > > >
          > > >
          > > > Ethernet adapter Local Area Connection:
          > > >
          > > > Connection-specific DNS Suffix . :
          > > > IP Address. . . . . . . . . . . . : 192.168.1.100
          > > > Subnet Mask . . . . . . . . . . . : 255.255.255.0
          > > > IP Address. . . . . . . . . . . . : fe80::211:11ff: fee1:f303%4
          > > > Default Gateway . . . . . . . . . : 192.168.1.1
          > > >
          > > > Tunnel adapter Teredo Tunneling Pseudo-Interface:
          > > >
          > > > Connection-specific DNS Suffix . :
          > > > IP Address. . . . . . . . . . . . :
          > > > 3ffe:831f:4004: 1956:0:fbde:bd0 a:e50b
          > > > IP Address. . . . . . . . . . . . : fe80::5445:5245 :444f%5
          > > > Default Gateway . . . . . . . . . : ::
          > > >
          > > > Tunnel adapter Automatic Tunneling Pseudo-Interface:
          > > >
          > > > Connection-specific DNS Suffix . :
          > > > IP Address. . . . . . . . . . . . : fe80::5efe:192. 168.1.100%2
          > > > Default Gateway . . . . . . . . . :
          > > >
          > > > E:\UserData\Den nis Lee Bieber\My Documents>
          > > > **** END of captured output
          > > > **** START of captured output
          > > > dir
          > > > Volume in drive E is Data
          > > > Volume Serial Number is 2626-D991
          > > >
          > > > Directory of E:\UserData\Den nis Lee Bieber\My Documents
          > > >
          > > > 10/24/2005 09:23 AM <DIR>
          > > > .
          > > > 10/24/2005 09:23 AM <DIR>
          > > > ..
          > > > 07/25/2005 10:39 PM <DIR>
          > > > .metadata
          > > > 10/06/2005 09:54 AM <DIR>
          > > > Ada Progs
          > > > 08/13/2005 02:01 PM <DIR>
          > > > Agent Data
          > > > 10/21/2005 09:29 AM 421,820 apress_offer.pd f
          > > > 07/03/2005 11:36 AM 132 cp.py
          > > > 07/17/2005 12:25 PM <DIR>
          > > > Cyberlink
          > > > 07/06/2005 09:32 AM 102,400 db1.mdb
          > > > 07/26/2005 12:20 AM 26,614 eclipse_code.xm l
          > > > 10/24/2005 01:08 AM <DIR>
          > > > Eudora
          > > > 06/24/2005 08:50 PM 667 fake_oosums.ads
          > > > 06/24/2005 08:50 PM 695 fake_oosums.ali
          > > > 09/06/2005 09:01 PM <DIR>
          > > > Genealogy
          > > > 07/13/2005 10:56 PM <DIR>
          > > > HomeSite
          > > > 05/08/2005 01:05 PM <DIR>
          > > > Investing
          > > > 10/21/2005 10:04 PM <DIR>
          > > > Java Progs
          > > > 08/04/2005 10:13 PM 162 main.py
          > > > 10/11/2005 10:43 PM <DIR>
          > > > My Downloads
          > > > 05/01/2005 10:31 AM <DIR>
          > > > My eBooks
          > > > 04/22/2005 12:09 AM <DIR>
          > > > My Music
          > > > 07/10/2005 11:43 AM <DIR>
          > > > My Pictures
          > > > 06/29/2005 11:55 PM <DIR>
          > > > My PSP Files
          > > > 05/23/2005 09:30 AM <DIR>
          > > > My Videos
          > > > 05/01/2005 12:49 PM <DIR>
          > > > Office Documents
          > > > 06/27/2005 03:19 PM 7,961,778
          > > > org.eclipse.jdt .doc.user.I2005 0627-1435.pdf
          > > > 06/27/2005 03:19 PM 6,791,109
          > > > org.eclipse.pla tform.doc.user. I20050627-1435.pdf
          > > > 10/11/2005 10:52 PM 56 oth_tsr_rm_750. ram
          > > > 07/20/2005 09:32 AM 108,457 parkerred15yc.j pg
          > > > 09/03/2005 10:36 PM <DIR>
          > > > Python Progs
          > > > 10/20/2005 10:38 PM <DIR>
          > > > Quicken
          > > > 07/10/2005 12:09 PM 3,356,248 results.xml
          > > > 06/11/2005 12:03 PM 935 Scout_Ship Database.lnk
          > > > 07/03/2005 12:38 PM <DIR>
          > > > Scout_Ship My Documents
          > > > 10/24/2005 09:23 AM 971 Script1.py
          > > > 09/25/2005 12:40 PM 1,107 Script1_old.py
          > > > 08/28/2005 11:47 AM <DIR>
          > > > SimpleMu Logs
          > > > 06/24/2005 08:56 PM 1,201 student_pack.ad s
          > > > 06/24/2005 08:49 PM 1,144 student_pack.ad s.0
          > > > 06/24/2005 08:56 PM 1,342 student_pack.al i
          > > > 08/02/2005 11:39 PM 4,096 t.DOC
          > > > 06/20/2005 10:11 AM 104 t.rx
          > > > 08/05/2005 08:41 PM 66,452 Untitled-1.tif
          > > > 08/05/2005 08:41 PM <DIR>
          > > > VCheck
          > > > 10/03/2005 02:58 AM <DIR>
          > > > Visual Studio
          > > > 10/03/2005 02:51 AM <DIR>
          > > > Visual Studio 2005
          > > > 21 File(s) 18,847,490 bytes
          > > > 25 Dir(s) 267,162,845,184 bytes free
          > > >
          > > > E:\UserData\Den nis Lee Bieber\My Documents>
          > > > **** END of captured output
          > > >
          > > > E:\UserData\Den nis Lee Bieber\My Documents>
          > > >
          > > > -=-=-=-=-=-=-=-=-
          > > >
          > > > Note that my "getLine()" has to return on either a real EOL, OR on
          > > > the end of a command prompt ("stuff>"). I also had to initialize the
          > > > prompt at the start. If someone issued a "cd" command to the subprocess,
          > > > the prompt would be all out of sequence, and the code would hang.
          > > >
          > > > You'll also note that the prompt /ends/ a capture sequence, and the
          > > > next command is the start of the /next/ capture sequence.
          > > >
          > > > --
          > > > > =============== =============== =============== =============== == <
          > > > > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
          > > > > wulfraed@dm.net | Bestiaria Support Staff <
          > > > > =============== =============== =============== =============== == <
          > > > > Home Page: <http://www.dm.net/~wulfraed/> <
          > > > > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color][/color][/color]

          Comment

          • Dennis Lee Bieber

            #6
            Re: Read/Write from/to a process

            On 24 Oct 2005 10:17:39 -0700, "jas" <codecraig@gmai l.com> declaimed the
            following in comp.lang.pytho n:
            [color=blue]
            > Thanks, that is certainly a start. As you mentioned, the "cd" could is
            > an issue.
            >
            > Perhaps checking to see if the line ends with ">" is sufficient?[/color]

            That would work IF you knew that was the end of the line. Look at my
            code -- the > is being treated AS the signal for EOL because a prompt
            from the system does NOT have a <cr><lf> sequence. (A more robust
            version of the above would assume that if the text up to the > is NOT
            the prompt, the line is not complete, read some more...)
            --[color=blue]
            > =============== =============== =============== =============== == <
            > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
            > wulfraed@dm.net | Bestiaria Support Staff <
            > =============== =============== =============== =============== == <
            > Home Page: <http://www.dm.net/~wulfraed/> <
            > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color]

            Comment

            • Dennis Lee Bieber

              #7
              Re: Read/Write from/to a process

              On 24 Oct 2005 10:38:43 -0700, "jas" <codecraig@gmai l.com> declaimed the
              following in comp.lang.pytho n:
              [color=blue]
              > What about having a thread which reads from subprocess.Pope n()'s
              > stdout...instea d of read/write, read/write. just always read, and
              > write when needed?
              >[/color]
              Regardless of how you do it, you still have to have a means of
              detecting when the subprocess has stopped for input (IE, it is at a
              prompt which did not supply a <cr><lf> sequence). Unfortunately, on
              Windows, the select() function only works with sockets, and not files,
              or you could do a simple select with time-out... Say one second... If no
              read data is available after one second assume a system prompt is
              present.

              You might want to see if http://pexpect.sourceforge.net/ has
              anything of use... Whoops -- no... Doesn't work on base Windows...



              {And PLEASE trim your replies -- there is a reason top-posting is
              frowned upon, besides the fact that people coming in cold end up reading
              stuff in the reverse order: top-posting is like Jeopardy, one sees the
              answer and then has to figure out the question... But the other reason
              is that top-posting software tends to propagate meaningless quotes
              because the quote is below, and ignored by the top-poster when making
              comment... You made three responses and quoted my couple of hundred
              lines each time, yet the only relevant substance was the paragraph about
              detecting EOL or prompt}
              --[color=blue]
              > =============== =============== =============== =============== == <
              > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
              > wulfraed@dm.net | Bestiaria Support Staff <
              > =============== =============== =============== =============== == <
              > Home Page: <http://www.dm.net/~wulfraed/> <
              > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color]

              Comment

              • jas

                #8
                Re: Read/Write from/to a process

                So it seems there is no good way to handle "interactiv e" processes on
                windows using python. By interactive I mean processes/commands that
                require user interaction, such as telnet or del (to delete a file or
                directory sometimes you need to confirm with a yes or no), date, etc.

                os.system gives the exact behavior, but you can't redirec the output.
                pexpect isn't supported on windows. Even with subprocess you can't
                handle all/most cases..since you have to do things like look for he
                prompt.

                I modified the original suggestion so it would update the prompt, in
                case the user did a "cd.." ..which works fine now. However, if a user
                tries to do, "del tmp123" ...windows prompts for a "are you sure you
                want to delete... Y/N?" ...so the code hangs.

                I can't believe no one else has done this yet..or if they have, it
                hasn't been widely discussed.

                Any other suggestions?

                Comment

                • Steve Holden

                  #9
                  Re: Read/Write from/to a process

                  jas wrote:[color=blue]
                  > So it seems there is no good way to handle "interactiv e" processes on
                  > windows using python. By interactive I mean processes/commands that
                  > require user interaction, such as telnet or del (to delete a file or
                  > directory sometimes you need to confirm with a yes or no), date, etc.
                  >
                  > os.system gives the exact behavior, but you can't redirec the output.
                  > pexpect isn't supported on windows. Even with subprocess you can't
                  > handle all/most cases..since you have to do things like look for he
                  > prompt.
                  >
                  > I modified the original suggestion so it would update the prompt, in
                  > case the user did a "cd.." ..which works fine now. However, if a user
                  > tries to do, "del tmp123" ...windows prompts for a "are you sure you
                  > want to delete... Y/N?" ...so the code hangs.
                  >
                  > I can't believe no one else has done this yet..or if they have, it
                  > hasn't been widely discussed.
                  >
                  > Any other suggestions?
                  >[/color]
                  Look at how you might do it in other languages. Then you'll realise this
                  isn't (just) a Python problem.

                  regards
                  Steve
                  --
                  Steve Holden +44 150 684 7255 +1 800 494 3119
                  Holden Web LLC www.holdenweb.com
                  PyCon TX 2006 www.python.org/pycon/

                  Comment

                  • jas

                    #10
                    Re: Read/Write from/to a process

                    Steve Holden wrote:[color=blue]
                    > Look at how you might do it in other languages. Then you'll realise this
                    > isn't (just) a Python problem.[/color]

                    Yea your right. However, for example, in Java, one can use the Process
                    class, and then read from the stream until its the end (i.e. -1 is
                    returned). However, with Python when reading from
                    subprocess.Pope n.stdout ...I don't know when to stop (except for
                    looking for a ">" or something). Is there a standard, like read until
                    "-1" or something?

                    As I mentioned, os.system("cmd" ) gives me exactly the
                    output/interactivity I need...but I can't redirect the output.

                    Thanks.

                    Comment

                    • Michael Schneider

                      #11
                      Re: Read/Write from/to a process

                      Jas,

                      I use a python called twisted to run processes as you describe.

                      Twisted is an event-driven framework that brings a change in the
                      way that you look at things.

                      take a look at:



                      Good luck, hope this is useful,
                      Mike


                      jas wrote:[color=blue]
                      > Hi,
                      > I would like to start a new process and be able to read/write from/to
                      > it. I have tried things like...
                      >
                      > import subprocess as sp
                      > p = sp.Popen("cmd.e xe", stdout=sp.PIPE)
                      > p.stdin.write(" hostname\n")
                      >
                      > however, it doesn't seem to work. I think the cmd.exe is catching it.
                      >
                      > I also tried
                      > f = open("out.txt", "w")
                      > sys.stdout = f
                      > os.system("cmd. exe")
                      >
                      > ..but out.txt didn't contain any output from cmd.exe
                      >
                      > So, how can I create a process (in this case, cmd.exe) on Windows and
                      > be able to read/write from/to it?
                      >
                      > Thanks
                      >[/color]


                      --
                      The greatest performance improvement occurs on the transition of from
                      the non-working state to the working state.

                      Comment

                      • Donn Cave

                        #12
                        Re: Read/Write from/to a process

                        Quoth "jas" <codecraig@gmai l.com>:
                        | Steve Holden wrote:
                        |> Look at how you might do it in other languages. Then you'll realise this
                        |> isn't (just) a Python problem.
                        |
                        | Yea your right. However, for example, in Java, one can use the Process
                        | class, and then read from the stream until its the end (i.e. -1 is
                        | returned). However, with Python when reading from
                        | subprocess.Pope n.stdout ...I don't know when to stop (except for
                        | looking for a ">" or something). Is there a standard, like read until
                        | "-1" or something?

                        Sure, end of file is '', a string with 0 bytes. That means the other
                        end of the pipe has closed, usually due to exit of the other process
                        that was writing to it. Not much help for you there, nor would the
                        Java equivalent be, I presume.

                        Even on UNIX, where pipes are a mainstay of ordinary applications,
                        this one would very likely need a pseudotty device instead, to prevent
                        C library block buffering, and it would still be difficult and unreliable.

                        Ironically the best support I've seen came from a platform that didn't
                        use pipes much at all, VAX/VMS (I put that in the past tense because
                        for all I know it may have evolved in this respect.) The pipe-like
                        VMS device was called a "mailbox", and the interesting feature was
                        that you could be notified when a read had been queued on the device.

                        Donn Cave, donn@drizzle.co m

                        Comment

                        • Dennis Lee Bieber

                          #13
                          Re: Read/Write from/to a process

                          On 25 Oct 2005 05:22:20 -0700, "jas" <codecraig@gmai l.com> declaimed the
                          following in comp.lang.pytho n:
                          [color=blue]
                          > So it seems there is no good way to handle "interactiv e" processes on
                          > windows using python. By interactive I mean processes/commands that
                          > require user interaction, such as telnet or del (to delete a file or
                          > directory sometimes you need to confirm with a yes or no), date, etc.
                          >[/color]
                          telnetlib includes an "expect" method...
                          [color=blue]
                          > os.system gives the exact behavior, but you can't redirec the output.
                          > pexpect isn't supported on windows. Even with subprocess you can't
                          > handle all/most cases..since you have to do things like look for he
                          > prompt.[/color]

                          That applies to any OS... If you have no IPC signalling mechanism
                          that the other process has completed an output phase and is now waiting
                          for input, you must scan for whatever is the "current" prompt. Even an
                          "expect" module is "expecting" to find something you had to specify in
                          advance.

                          Heck... How do YOU recognize that an application running in a
                          command window is waiting for input?

                          I suspect you do it by reading the output text and recognizing that
                          the cursor is on a line that looks like a prompt. The main difference is
                          that you have cognitive understanding of what IS the prompt, and can
                          recognize the differences between, say an [abort, retry, exit] prompt
                          and c:\junk> prompt. To programmaticall y handle this situation, you have
                          to code the logic to recognize the two possible prompts.
                          [color=blue]
                          >
                          > I modified the original suggestion so it would update the prompt, in
                          > case the user did a "cd.." ..which works fine now. However, if a user
                          > tries to do, "del tmp123" ...windows prompts for a "are you sure you
                          > want to delete... Y/N?" ...so the code hangs.
                          >
                          > I can't believe no one else has done this yet..or if they have, it
                          > hasn't been widely discussed.
                          >
                          > Any other suggestions?[/color]

                          Don't try to do a pass-through of everything to a command
                          interpreter -- instead write your own command interpreter IN Python.

                          Parse "cd ..." => os.chdir("...")
                          "del ..." => os.remove("..." )

                          etc.

                          Basically, any command that can change the environment should be
                          handled by your program, not a pass through. But of course, if you then
                          try to handle an external interactive program, you'd have to know what
                          it uses for prompts.

                          The other possibility (and I have a dental appointment to get to so
                          can't spend another hour trying to code it) is to, yes, use a thread to
                          fetch characters one at a time from the subprocess output. Use a Queue
                          to pass those characters to another thread for assembly into "lines" (on
                          a <cr> or <lf> you have an obvious line -- pass it on to the main
                          processing thread). The Queue process will need to loop until the queue
                          has been empty for some defined amount of time -- this delay with no
                          data would be the signal that a prompt message likely has been received,
                          and any "incomplete " line would be returned to the main process along
                          with a flag saying "prompt" [pity select() can't be used, or you could
                          combine the Queue processing and read-1-char thread into a single
                          thread]
                          --[color=blue]
                          > =============== =============== =============== =============== == <
                          > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
                          > wulfraed@dm.net | Bestiaria Support Staff <
                          > =============== =============== =============== =============== == <
                          > Home Page: <http://www.dm.net/~wulfraed/> <
                          > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color]

                          Comment

                          • Dennis Lee Bieber

                            #14
                            Re: Read/Write from/to a process

                            On Tue, 25 Oct 2005 15:29:12 -0000, "Donn Cave" <donn@drizzle.c om>
                            declaimed the following in comp.lang.pytho n:
                            [color=blue]
                            > Ironically the best support I've seen came from a platform that didn't
                            > use pipes much at all, VAX/VMS (I put that in the past tense because
                            > for all I know it may have evolved in this respect.) The pipe-like
                            > VMS device was called a "mailbox", and the interesting feature was
                            > that you could be notified when a read had been queued on the device.
                            >[/color]
                            Followed by the Amiga... The Amiga IPC used "message ports" (linked
                            lists owned by the creating process to which, if "public" [named], other
                            processes could send message packets). The Amiga port of REXX made use
                            of message ports as its native IPC...

                            address SOME_APPLICATIO N

                            would redirect all "non-REXX" statements to the message port named
                            "SOME_APPLICATI ON"; the default being "address COMMAND" -- a shell
                            interpreter. Then, any non-REXX statement would be processed by the
                            shell interpreter -- and the easiest way to force a non-REXX statement
                            was to put a quote mark around it (or the first word of it)

                            "delete" my_file_var

                            would translate my_file_var to whatever had been assigned to it earlier,
                            and pass a delete command to the shell.

                            address ED

                            would now route such statements to the "ed" editor

                            No explicit "write" needed to send stuff to the subprocess.
                            --[color=blue]
                            > =============== =============== =============== =============== == <
                            > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
                            > wulfraed@dm.net | Bestiaria Support Staff <
                            > =============== =============== =============== =============== == <
                            > Home Page: <http://www.dm.net/~wulfraed/> <
                            > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color]

                            Comment

                            • jas

                              #15
                              Re: Read/Write from/to a process

                              I have setup multiple threads and a queue...which is working pretty
                              good. But I have one other issue...I have a new thread (since it is
                              different issue) here:


                              if you get chance, would you mind checking that out.

                              Thanks!

                              Comment

                              Working...