You have to open the subprocess like this:

import subprocess
cmd = subprocess.Popen(['./myprogram'], stdin=subprocess.PIPE)

This means that cmd will have a .stdin you can write to; print by default sends output to your Python script's stdout, which has no connection with the subprocess' stdin. So do that:

cmd.stdin.write('1\n')  # tell myprogram to select 1

and then quite probably you should:

cmd.stdin.flush()  # don't let your input stay in in-memory-buffers

or

cmd.stdin.close()  # if you're done with writing to the subprocess.

PS If your Python script is a long-running process on a *nix system and you notice your subprocess has ended but is still displayed as a Z (zombie) process, please check that answer.

Answer from tzot on Stack Overflow
🌐
Quora
quora.com › What-is-the-best-way-to-run-a-C-code-in-Python-subprocess-vs-Cython
What is the best way to run a C code in Python (subprocess vs. Cython)? - Quora
Answer: You have omitted two other means of calling C code : * ctypes and the CFFI interface : You compile your C code into a normal C library (as might be called from a C program), and then use ctypes to use that C library from Python * CAPI and writing a C extension : You write a C library, ...
Discussions

Running a C executable inside a python program - Stack Overflow
To run my C code, I have taken one command line argument : filestem. I executed that code using : ./executable_file filestem > outputfile · Where I have got my desired output inside outputfile · Now I want to take that executable and run within a python code. ... import subprocess import sys ... More on stackoverflow.com
🌐 stackoverflow.com
subprocess, invoke C-program from within Python - Stack Overflow
I am trying to invoke a C-program, named “drule.c”, from within my Python-program “drulewrapper.py”. I am trying to use "subprocess" but cannot get it to work. 1) I compile “drule.c” on the Mac’s More on stackoverflow.com
🌐 stackoverflow.com
How do I create a python file that interacts with c executable, and saves its output to variables?
the problem is that the c program is expecting info on it's stdin channel, so it is hanging until it receives it. so either you need to feed it a line of data and an EOF so that it can complete. (i haven't used popen in a long time so if others have that info that would be appreciated) or you need to wrap your program with something else. like instead of python3 dummy.py something like echo magicdata | python3 dummy.py or possibly, depending on if popen will do the shell interface for you: bash -c "echo magicdata | python3 dummy.py" you're definitely treading on interesting but potentially complex ground, writing something that does two-way communication with a separate process. it's not wrong or unheard of, but it's not as simple as a system call and stdout capture. good question and good work getting this far on it, too. More on reddit.com
🌐 r/learnprogramming
4
3
February 3, 2022
python - C program and subprocess - Stack Overflow
what if I'm not able to edit and compile again the C code?? Is there a way to do that? I know there are other python libraries which do it good, but I was trying not to use them... ... Use the pexpect library. It runs the subprocess in a pty so its output will not be buffered. More on stackoverflow.com
🌐 stackoverflow.com
🌐
Python
docs.python.org › 3 › library › subprocess.html
Subprocess management — Python 3.14.7 documentation
... Availability: not Android, not iOS, not WASI. This module is not supported on mobile platforms or WebAssembly platforms. The recommended approach to invoking subprocesses is to use the run() function ...
Top answer
1 of 2
3

subprocess.run has optional stdout argument, you might give it file handle, so in your case something like

import subprocess
import sys
filestem = sys.argv[1]
with open('outputfile','wb') as f:
    subprocess.run(['/home/dev/executable_file', filestem],stdout=f)

should work. I do not have ability to test it so please run it and write if it does work as intended

2 of 2
0

You have several options:

NOTE - Tested in CentOS 7, using Python 2.7

1. Try pexpect:

"""Usage: executable_file argument ("ex. stack.py -lh")"""
import pexpect

filestem = sys.argv[1]
# Using ls -lh >> outputfile as an example
cmd = "ls {0} >> outputfile".format(filestem)
command_output, exitstatus = pexpect.run("/usr/bin/bash -c '{0}'".format(cmd), withexitstatus=True)
if exitstatus == 0:
    print(command_output)
else:
    print("Houston, we've had a problem.")

2. Run subprocess with shell=true (Not recommended):

"""Usage: executable_file argument ("ex. stack.py -lh")"""
import sys
import subprocess

filestem = sys.argv[1]
# Using ls -lh >> outputfile as an example
cmd = "ls {0} >> outputfile".format(filestem)
result = subprocess.check_output(shlex.split(cmd), shell=True)  # or subprocess.call(cmd, shell=True)
print(result)

It works, but python.org frowns upon this, due to the chance of a shell injection: see "Security Considerations" in the subprocess documentation.

3. If you must use subprocess, run each command separately and take the SDTOUT of the previous command and pipe it into the STDIN of the next command:

p = subprocess.Popen(cmd, stdin=PIPE, stdout=PIPE)
stdout_data, stderr_data = p.communicate()
p = subprocess.Popen(cmd, stdin=stdout_data, stdout=PIPE)
etc...

Good luck with your code!

🌐
Stack Overflow
stackoverflow.com › questions › 49541728 › subprocess-invoke-c-program-from-within-python
subprocess, invoke C-program from within Python - Stack Overflow
1) I compile “drule.c” on the Mac’s terminal and all works okay: ... Fyi, the input -- “D11” -- are axioms in predicate logic; the output -- “>P>Q>RQ” -- is the theorem that is proven and which I then want to process further in my Python program. 2) I write a short Python program (drulewrapper.py) and compile it: From subprocess import call def CheckString(): call(“./drule”, “D11”)
🌐
howtos
wgilpin.com › howto › howto_cython.html
Running a C/C++ executable from within Python, without any IO | howtos
Now - Then, in your Python script, use some variant of this: def test_no_io(): ''' Run a process that takes no input and produces no output ''' ## Shell=False helps the process terminate process = subprocess.Popen("./hello", shell=False) ## Get exit codes out, err = process.communicate() errcode = process.returncode print(errcode) process.kill() process.terminate()
🌐
Reddit
reddit.com › r/learnprogramming › how do i create a python file that interacts with c executable, and saves its output to variables?
r/learnprogramming on Reddit: How do I create a python file that interacts with c executable, and saves its output to variables?
February 3, 2022 -

Hi, I have this simple c program:

#include <stdio.h>
void secretFunction() { printf("Congratulations!\n"); printf("You have entered in the secret function!\n"); }
void echo() { char buffer[20];
printf("Enter some text:\n"); scanf("%s", buffer); printf("You entered: %s\n", buffer);}
int main() { echo();
return 0; }

It includes a buffer overflow, but that's not really the important part right now. This is what the output looks like:

Enter some text:
enteringmyname
You entered: enteringmyname

What I am trying to do, is create a python file that is able to run this file, save the lines that it gives to some variables, and then give it some input depending on that output.

Currently this is what I have:

import subprocess

p = subprocess.Popen("./vuln_nostack", shell=False)

p.communicate()

This runs the file like I want, and then just runs the file in the python terminal.

This is not reaaally what I want though.

I want to be able to save the lines that it outputs to variables in my python program, and then output something.

I then tried all kinds of things to make a program that could interact a little more with the executable.

I made a python script that imitates, and does the same thing as the c program:

inp = input("Enter some text:\n")
print("you entered: " + inp)

And then I made this python program to interact with it:

import subprocess
command = "python3 dummy.py"
p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True, universal_newlines=True)
v = p.stdout.readline() print(v) output, err = p.communicate(input="{}\n".format(v))
print(output)

and this does exactly what I want, I can save the ouput, and input something based on it.

But when I run this exact same program, but instead point it to the c executable, the program just hangs, and nothing happens.

Why does this happen? and can I get my python file to talk to the executable in the way that I want?

Top answer
1 of 2
3

I really can't find something that explain this behaviour; can someone help me understanding?

There are at least two issues here:

  1. the C program's standard output is to a non-interactive device (a pipe) and therefore the output is fully buffered. The output will be accumulated in memory, only being sent to the output device when (i) the buffer fills, or (ii) it is manually flushed, or (iii) the program terminates normally.

  2. the C program runs indefinitely, with no way to make it terminate normally. Not even end-of-file on its standard input will make it stop.

On the Python side, then, the script is waiting for the subprocess's output to be flushed, whereas the subprocess needs to read and echo more data (probably a lot of it) before that will happen. This is a deadlock.

Your best approach depends on how well the example C program models the behavior of the one in which you're really interested.

  • If it's faithful in every relevant detail, then the only thing you can reasonably do is keep writing to the subprocess's stdin until something pops out on its stdout. You probably want to do the data pushing in a separate thread, to avoid reproducing exactly the same kind of deadlock you already saw.

  • If it recognizes some kind of clean termination signal, such as a "quit" command or EOF on its standard input, then have the Python side send that signal before trying to read the output. Indeed, you already close stdin, so perhaps you don't actually need to do anything to accommodate the real program.

Note well that the first alternative leaves the subprocess running. You will want to ensure that it terminates. By terminate()ing or kill()ing it, if that's what it takes.

2 of 2
2

Change these:

  • Send a separator between the numbers read by the C program. scanf(3) accepts any non-digit byte as separator. For easiest buffering, send a newline (e.g. .write(b'42\n')) from Python. Without a separator, scanf(3) will wait for more digits indefinitely.

  • After each write (both in C and Python), flush the output.

This works for me:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int n;
    while (1){
        scanf("%d", &n);
        printf("%d\n", n);
        fflush(stdout);  /* I've added this line only. */
    }
    return 0;
}
import subprocess

p = subprocess.Popen(
    ('./a.out',), stdin=subprocess.PIPE, stdout=subprocess.PIPE)
try:
  print('A'); p.stdin.write(b'42 '); p.stdin.flush()
  print('B'); print(repr(p.stdout.readline()));
  print('C'); p.stdin.write(b'43\n'); p.stdin.flush()
  print('D'); print(repr(p.stdout.readline()));
finally:
  print('E'); print(p.kill())

The reason why your original C program works when run interactively within the terminal window is that in C the output is automatically flushed when a newline (\n) is written to the terminal. Thus printf("%d\n", n); does an implicit fflush(stdout); in the end.

The reason why your original C program doesn't work when run from Python with subprocess is that it writes its output to a pipe (rather than to a terminal), and there is no autoflush to a pipe. What happens is that the Python program is waiting for bytes, and the C program doesn't write those bytes to the pipe, but it is waiting for more bytes (in the next scanf), so both programs are waiting for the other indefinitely. (However, there would be a partial autoflush after a few KiB (typically 8192 bytes) of output. But a single decimal number is too short to trigger that.)

If it's not possible to change the C program, then you should use a terminal device instead of a pipe for communication between the C and the Python program. The pty Python module can create the terminal device, this works for me with your original C program:

import os, pty, subprocess

master_fd, slave_fd = pty.openpty()
p = subprocess.Popen(
    ('./a.out',), stdin=slave_fd, stdout=slave_fd,
    preexec_fn=lambda: os.close(master_fd))
try:
  os.close(slave_fd)
  master = os.fdopen(master_fd, 'rb+', buffering=0)
  print('A'); master.write(b'42\n'); master.flush()
  print('B'); print(repr(master.readline()));
  print('C'); master.write(b'43\n'); master.flush()
  print('D'); print(repr(master.readline()));
finally:
  print('E'); print(p.kill())

If you don't want to send newlines from Python, here is a solution without them, it works for me:

import os, pty, subprocess, termios

master_fd, slave_fd = pty.openpty()
ts = termios.tcgetattr(master_fd)
ts[3] &= ~(termios.ICANON | termios.ECHO)
termios.tcsetattr(master_fd, termios.TCSANOW, ts)
p = subprocess.Popen(
    ('./a.out',), stdin=slave_fd, stdout=slave_fd,
    preexec_fn=lambda: os.close(master_fd))
try:
  os.close(slave_fd)
  master = os.fdopen(master_fd, 'rb+', buffering=0)
  print('A'); master.write(b'42 '); master.flush()
  print('B'); print(repr(master.readline()));
  print('C'); master.write(b'43\t'); master.flush()
  print('D'); print(repr(master.readline()));
finally:
  print('E'); print(p.kill())
Find elsewhere
🌐
Quora
quora.com › How-do-I-write-a-Python-script-to-run-a-C-program
How to write a Python script to run a C program - Quora
Answer (1 of 6): I assume you want to both compile and run the code! You can follow following steps: Since i am using windows to run the "gcc" command i did these settings: 1. Install DEV-CPP 2. Now set the path of "gcc" file in your environmental variables i.e. "C:\Program Files (x86)\Dev-Cpp\M...
🌐
Medium
tanishq0917t.medium.com › executing-java-code-or-c-code-from-python-b5848d81c3d0
Executing Java Code or C++ Code from Python | by Tanishq Rawat | Medium
October 25, 2021 - So, First of all let me clear all ... for executing subprocess from python script. The syntax is that we need to pass a list to run method ......
Top answer
1 of 3
6

To complement @Jonathan Leffler's and @alastair's helpful answers:

Assuming you control the string you're passing to the shell for execution, I see nothing wrong with using the shell for convenience. [1]

subprocess.call() has an optional Boolean shell parameter, which causes the command to be passed to the shell, enabling I/O redirection, referencing environment variables, ...:

subprocess.call("./x <inp.txt", shell = True)

Note how the entire command line is passed as a single string rather than an array of arguments.


[1] Avoid use of the shell in the following cases:

  • If your Python code must run on platforms other than Unix-like ones, such as Windows.
  • If performance is paramount.
  • If you find yourself "outsourcing" tasks better handled on the Python side.

If you're concerned about lack of predictability of the shell environment (as @alastair is):

  • subprocess.call with shell = True always creates non-interactive non-login instances of /bin/sh - note that it is NOT the user's default shell that is used.

  • sh does NOT read initialization files for non-interactive non-login shells (neither system-wide nor user-specific ones).

    • Note that even on platforms where sh is bash in disguise, bash will act this way when invoked as sh.
  • Every shell instance created with subprocess.call with shell = True is its own world, and its environment is neither influenced by previous shell instances nor does it influence later ones.

  • However, the shell instances created do inherit the environment of the python process itself:

    • If you started your Python program from an interactive shell, then that shell's environment is inherited. Note that this only pertains to the current working directory and environment variables, and NOT to aliases, shell functions, and shell variables.

    • Generally, that's a feature, given that Python (CPython) itself is designed to be controllable via environment variables (for 2.x, see https://docs.python.org/2/using/cmdline.html#environment-variables; for 3.x, see https://docs.python.org/3/using/cmdline.html#environment-variables).

    • If needed, you can supply your own environment to the shell via the env parameter; note, however, that you'll have to supply the entire environment in that event, potentially including variables such as USER and HOME, if needed; simple example, defining $PATH explicitly:

      subprocess.call('echo $PATH', shell = True, \
                      env = { 'PATH': '/sbin:/bin:/usr/bin' })
      
2 of 3
4

The shell does I/O redirection for a process. Based on what you're saying, the subprocess module does not do I/O redirection like that. To demonstrate, run:

subprocess.call(["sh","-c", "./x <inp.txt"])

That runs the shell and should redirect the I/O. With your code, your program ./x is being given an argument <inp.txt which it is ignoring.

NB: the alternative call to subprocess.call is purely for diagnostic purposes, not a recommended solution. The recommended solution involves reading the (Python 2) subprocess module documentation (or the Python 3 documentation for it) to find out how to do the redirection using the module.

import subprocess
i_file = open("inp.txt")
subprocess.call("./x", stdin=i_file)
i_file.close()

If your script is about to exit so you don't have to worry about wasted file descriptors, you can compress that to:

import subprocess
subprocess.call("./x", stdin=open("inp.txt"))
🌐
The Coding Forums
thecodingforums.com › archive › archive › python
Execute C code through Python | Python | Coding Forums
October 26, 2005 - compile helloWorld, and run: import subprocess subprocess.call("helloWorld") (any special reason why you couldn't figure this out yourself, given the example provided by gsteff ?) </F> Click to expand... There is a reason (though it is not special). I'm new to Python.
🌐
DataCamp
datacamp.com › tutorial › python-subprocess
An Introduction to Python Subprocess: Basics and Examples | DataCamp
April 23, 2026 - Let's now take a look at some Python subprocess examples. The subprocess.run() method is a convenient way to run a subprocess and wait for it to complete. It lets you choose the command to run and add options like arguments, environment variables, and input/output redirections.
🌐
Dataquest
dataquest.io › home › blog › python subprocess: the simple beginner's tutorial
Python Subprocess: The Simple Beginner's Tutorial (2023)
February 19, 2025 - In fact, this is the same as passing /usr/local/bin/python -c print('This is a subprocess') to the command line. Most of the code in this article will be in this format because it's easier to show the features of the run function.
🌐
Quora
quora.com › How-can-you-create-a-Python-script-that-executes-C-programs-like-an-exe-file
How to create a Python script that executes C programs, like an .exe file - Quora
Answer (1 of 4): Souyama Debnath's answer is essentially correct, but I want to add some opinions about best practices. Don’t use os.system. It opens a shell, which means it is vulnerable to injection, and it’s not as flexible. Use the subprocess module. How should you use the subprocess ...