简体   繁体   中英

Running an external executable in Python interactively

A simple C program is compiled using gcc test.c -o test.exe :

        /* TEST.C */
#include <stdio.h>
#include <string.h>
#define TRUE 1

int main (void)
{
  char p[256];
  strcpy(p, "start\0");
  printf("Welcome!\n");
  while (TRUE)
  {
    printf("Input: ");
    if (fgets(p, 255, stdin) == NULL)  break;
    if (p[0] == 'q')                   break;
    printf("You Entered: %s\n", p);
  }
  return 0;
}

The subprocess module in Python portends to start a program and grab its stdin and stdout . Simple test using the above program:

import subprocess
from subprocess import PIPE, STDOUT

output = open("test.out","w")
ris = subprocess.Popen(executable="test.exe", args="", stdin=PIPE,
                       stdout=output, stderr=STDOUT,
                       universal_newlines=True, shell=True)  
com = ris.communicate(input='bye\n')
com = ris.communicate(input='q\n')
output.close()

appears to loop infinitely on the first communicate command, filling test.out with:

Welcome!
You Entered: bye
You Entered: bye
You Entered: bye
You Entered: bye
.
.
.

until the user interrupts the python process. Using ris.stdin.write('bye\\n') instead of communicate does not seem to send input at all even when followed by ris.stdin.flush() .

What is the proper way to interactively run an executable with subprocess ? The intention is to leave a single instance of the program running in the background while multiple inputs are passed in through stdin and the corresponding outputs are read from stdout or stderr

In addition to the errors in your C program that have been mentioned, you are calling .communicate() more than once. .communicate() is single-use function that sends all of its data to the subprocess and waits for the subprocess to exit.

If you must use .communicate() , use it this way:

com = ris.communicate(input='bye\nq\n')

Alternatively, you can use ris.stdin.write() , like so:

import subprocess
from subprocess import PIPE, STDOUT

output = open("test.out","w")
ris = subprocess.Popen(executable="/tmp/test.exe", args="", stdin=PIPE,
                       stdout=output, stderr=STDOUT,
                       universal_newlines=True, shell=True)
com = ris.stdin.write('bye\n')
com = ris.stdin.write('q\n')
ris.stdin.flush()
output.close()
ris.wait()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM