#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2006
    Posts
    5
    Rep Power
    0

    Run external program in python


    Hi. Asume we have the following C++ program:

    Code:
    int main(int argc, char *argv[])
    {
        int number = 0;
        do {
            scanf("%d", &number);
            for(int x=1; x<=number; x++) {
                    printf("%d \n", x);
            }
        } while (number >= 1);
        
        return EXIT_SUCCESS;
    }
    It takes for input a positive, non-zero integer X end prints 1,2...,X. I want to run this program from a python program. The code:

    Code:
    (child_stdin, child_stdout, child_stderr) = os.popen3("example.exe")
    
    child_stdin.write("8")
    output = child_stdout.readline()
    while output != "":
       print output
       output = child_stdout.readline()
    It doesn't work at all. Any ideas? Thanx for your time!

    ps. The C++ program isn't the one i want to use, but if i manage to run this simple one i will be able to run the other too! (i hope )
  2. #2
  3. Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Dec 2004
    Location
    Meriden, Connecticut
    Posts
    1,797
    Rep Power
    154
    You could try using the os module's system() function.

    Code:
    import os
    print os.system('example.exe')
    That should execute example.exe and return whatever it returns. If you need to send it arguments:

    Code:
    os.system('example.exe 10')
    I havn't used Windows command-line in quite some time, so maybe you don't need to include the file extension part when calling a file and giving it arguments in the manner that I did.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2006
    Posts
    5
    Rep Power
    0

    !


    Originally Posted by Yegg`
    You could try using the os module's system() function.

    Code:
    import os
    print os.system('example.exe')
    That should execute example.exe and return whatever it returns. If you need to send it arguments:

    Code:
    os.system('example.exe 10')
    I havn't used Windows command-line in quite some time, so maybe you don't need to include the file extension part when calling a file and giving it arguments in the manner that I did.
    Thanks for the reply Yegg`, but i want to run the program interactively. Also, the external program doesn't have command line arguments. It takes input from keyboard and prints to screen. I want to control stdin & stdout that's why i tried os.popen. I tried also subprocess.popen and i manage to take some output -not 100% correct-, but i couldn't send any input!
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2006
    Posts
    5
    Rep Power
    0
    I think i found something. When i try this code:

    Code:
    import subprocess, os
    
    PIPE = subprocess.PIPE
    p = subprocess.Popen("example.exe", stdin=PIPE, stdout=PIPE)
    
    p.stdin.write("10")
    p.stdin.flush()
    print p.stdout.read() #Deadlock
    
    print "End of Execution"
    os.system("PAUSE")
    It think that the read() command is waiting the write() command, and this leads to a deadlock. The last two commands executed only if i stop the execution of "example.exe".

    BTW i did't mention in my previous posts, i 'm writing this program for windows, so goodbye fork(), FIFOS etc. etc.
  8. #5
  9. Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Feb 2005
    Posts
    588
    Rep Power
    64
    You might have to put a small delay in there, something like time.sleep(0.1) or p.wait()
    Last edited by Dietrich; June 27th, 2006 at 12:43 AM.
    Real Programmers always confuse Christmas and Halloween because Oct31 == Dec25
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2006
    Posts
    5
    Rep Power
    0
    I modified a bit the code. After some experiments i found that the "example.exe" is writing results in the pipe, but the read() statement in parent code doesn't work. So i left the stdout to the screen. Now at least i have a minimal functionality. If anyone knows how to capture ouput stream i'll be glad!
    Code:
    import subprocess, os
    
    PIPE = subprocess.PIPE
    p = subprocess.Popen("example.exe", stdin=PIPE)
    
    p.stdin.write("10")
    #p.stdin.flush()
    p.stdin.write("\r") #This might be unecessary
    #p.stdin.flush()
    p.stdin.write("\n")
    #p.stdin.flush()
    
    print "End of Execution"
    os.system("PAUSE")
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    London, England
    Posts
    1,585
    Rep Power
    1373
    The biggest problem with using pipes or popen variants is that the streams are buffered, so you cannot sychronise between sending data to the program and reading the response.

    If you are on a unix/linux system then take a look at pexpect. This is a python module for controlling interactive text based programs. It does some magic to open streams unbuffered, but unfortunately this does not work on Windows unless you run it in cygwin.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2006
    Posts
    5
    Rep Power
    0
    Thanx for the info DevCoach! To tell you the truth, after some experiments, i came to this conclusion, and i tried to set bufsize=1, with no efect . It seems that only if i send "exit data" to close the subprocess, the parent is able to read the pipe! I knew the pexpect module but i didn't know it works in cygwin! I'll try it, thanks again DevCoach!

IMN logo majestic logo threadwatch logo seochat tools logo