Thanks to the comment of @joan:
You can't. A C program (a program in any language) returns an integer status. You want to change the Python program so it gets the stdout (printf) of the C program rather than the status of the C program.
I do this in Python:
>>> from subprocess import check_output
>>> foo = check_output('./th', shell=True)
>>> foo
'17.9 51.0'
Answer from allcaps on Stack ExchangeHi, 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?
windows - Capture stdout from a running C program with Python - Stack Overflow
Run C program from Python and then capture output - Stack Overflow
Running a C executable inside a python program - Stack Overflow
c++ - Python Script to run a C Program - Stack Overflow
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
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!
Currently recommended way of running and controlling executables using Python is subprocess module. You can use different arguments, capture stdout, process it, or just redirect to arbitrary file. Have a look at documentation here https://docs.python.org/3.2/library/subprocess.html#module-subprocess
I'm not sure if this is what you're looking for, but you can use python to execute commands through the terminal. For example
import os
os.system("echo 'hello world'")
This will execute the terminal command >> echo 'hello world'
There is no such thing as a C script. If you meant a C program you need to compile spa.c and spa.h into an executable before running it.
If you use GCC in Linux or Mac OS X:
$ gcc -Wall spa.c -o spa
Will get you an executable named spa.
After that, you can run spa program from your Python script with:
from subprocess import call
call(["./spa", "args", "to", "spa"])
cinpy comes close using the awesome combination of tcc and ctypes
The following code is ripped from cinpy_test.py included in the package.
import ctypes
import cinpy
# Fibonacci in Python
def fibpy(x):
if x<=1: return 1
return fibpy(x-1)+fibpy(x-2)
# Fibonacci in C
fibc=cinpy.defc("fib",
ctypes.CFUNCTYPE(ctypes.c_long,ctypes.c_int),
"""
long fib(int x) {
if (x<=1) return 1;
return fib(x-1)+fib(x-2);
}
""")
# ...and then just use them...
# (there _is_ a difference in the performance)
print fibpy(30)
print fibc(30)
You can use a ThreadPool to run many tasks in parallel.
from multiprocessing.pool import ThreadPool
import subprocess
def f(x):
a, b = x
res = subprocess.check_output(["./a.out", str(a), str(b)])
return int(res.strip())
p = ThreadPool()
results = p.map(f, [(2,3), (5,6), (9,10)])
You can use subprocess.Popen to run multiple processes at once without using threads.
If the output from them is short enough to fit in the operating system buffers it is fairly easy:
To start a program asynchronously, use
subprocess.Popen(['command', args],stdout=subprocess.PIPE)
Just do that for all commands and place the result in an array.
Then:
for process in subprocesses:
process.wait()
stdout,stderr = process.communicate()
This will not work if the subprocesses outputs a lot of data, becasuse wait() will deadlock: The process want's to write more, but the buffer is full, and you are waiting for the process to finish before you read.
In that case you will need to look into select.poll() or similar API:s
The input to your C code should be taken by scanf.
C code: [test.c]
#include <stdio.h>
int main() {
int x;
scanf("%d",&x);
printf("Value is %d\n",x);
}
Compile:
gcc test.c -o foo
Python code:[test.py]
print (3)
Command :
python test.py | ./foo
Output:
Value is 3
Here standard input of C code gets changed from keyboard to the end of pipe.
And standard output of python code gets changed from monitor to beginning of pipe.
In C there are kernel level calls to perform this operation. Read about close() , dup() calls. I hope your concept will be cleared then. Good Luck :)
And you are actually trying to print command line arguments. But look at your command. You are not passing any arguments to myprogram. So, argc = 0.
Do this to make it work:
./myProgram `python -c 'print "a" '`
This works with argc / argv. Like Parnab said, there were no arguments given previously, as pipe puts your argument through stdin instead
This is one of the simplest ways to do this:
- Make your C program print its output on
stdout. This is the standard stream which is used byprintf(). - Make your python program read its input from
stdin. This is the standard stream which is used byinput(). Connect both programs on the command line with the pipe symbol
|like this:c-program | python script.py
Note that there are more ways to make two programs communicate. And there are more ways to write to stdout and to read from stdin.
The method described works on all major operating systems.
One of its biggest advantages is that you can develop each part independent from the other and test it on its own. In example, you can pipe the output of the C program into a file to check later. Similarly you can pipe the input of this or any other file into the python script.
The best way to do it is using the fileinput module as following:
import fileinput
for line in fileinput.input():
print(line.rstrip())
This loop will process every input line from stdin.
An then you could run something like
cat data.csv | python r.py
You could use subprocess.Popen. Sample code:
#include <iostream>
int sum(int a, int b) {
return a + b;
}
int main ()
{
int a, b;
std::cin >> a >> b;
std::cout << sum(a, b) << std::endl;
}
from subprocess import Popen, PIPE
program_path = "/home/user/sum_prog"
p = Popen([program_path], stdout=PIPE, stdin=PIPE)
p.stdin.write(b"1\n")
p.stdin.write(b"2\n")
p.stdin.flush()
result = p.stdout.readline().strip()
assert result == b"3"
python_program.py | cpp_program
On the command line will feed the standard output of python_program.py into the standard input of cpp_program.
This works for all executables, no matter what programming language they are written in.
One useful way is calling a python function within c, which is that you need instead of execute whole script.
As described in >> here
You can do like this to call the python file from the C program:
char command[50] = "python full_path_name\\file_name.py";
system(command);
This piece of code worked for me...
I didn't use # include < python2.7/Python.h>
You can write the results from the python file to any text file and then use the results stored in the text file to do whatever you want to do...
You can also have a look at this post for further help:
Calling python script from C++ and using its output