Python: How to execute an external program - python

How do I execute a program from within my program without blocking until the executed program finishes?
I have tried:
os.system()
But it stops my program till the executed program is stopped/closed. Is there a way to allow my program to keep running after the execution of the external program?

Consider using the subprocess module.
Python 2: http://docs.python.org/2/library/subprocess.html
Python 3: http://docs.python.org/3/library/subprocess.html
subprocess spawns a new process in which your external application is run. Your application continues execution while the other application runs.

You want subprocess.

You could use the subprocess module, but the os.system will also work. It works through a shell, so you just have to put an '&' at the end of your string. Just like in an interactive shell, it will then run in the background.
If you need to get some kind of output from it, however, you will most likely want to use the subprocess module.

You can use subprocess for that:
import subprocess
import codecs
# start 'yourexecutable' with some parameters
# and throw the output away
with codecs.open(os.devnull, 'wb', encoding='utf8') as devnull:
subprocess.check_call(["yourexecutable",
"-param",
"value"],
stdout=devnull, stderr=subprocess.STDOUT
)

Related

Start a bash session from python

I want to drop into a shell for a ctf competition I am working on. I am not allowed to use pwntools for this. I want to achieve something like following from python:
import os
os.system("/bin/bash &")
print("hello world") # assume I am writing to a file
os.system("fg") # does not work (but assume resuming shell /bin/bash)
I can't use subprocess since I need to drop into a shell. Not communicate back and forth with the bash process which would run in the background. Is there an easy way to approach this?
You want to use the subprocess module instead. fg is a shell built-in command that only works with job control in the shell itself.
import subprocess
p = subprocess.Popen(["bash"])
print('hello world')
p.wait()

Python subprocess.run C Program not working

I am trying to write the codes to run a C executable using Python.
The C program can be run in the terminal just by calling ./myprogram and it will prompt a selection menu, as shown below:
1. Login
2. Register
Now, using Python and subprocess, I write the following codes:
import subprocess
subprocess.run(["./myprogram"])
The Python program runs but it shows nothing (No errors too!). Any ideas why it is happening?
When I tried:
import subprocess
subprocess.run(["ls"])
All the files in that particular directory are showing. So I assume this is right.
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.
Maybe flush stdout?
print("", flush=True,end="")

Using subprocess.call to execute python file?

I am using subprocess.call in order to execute another python file. Considering that the script that will be called will never terminate the execution as it's inside an infinite loop, how can I make it possible for the original script to continue the execution after the subprocess call ?
Example:
I have script1.py which does some calculations and then calls script2.py using subprocess.call(["python", "script2.py"]), since it's inside an infinite loop the script1 gets stuck on execution, is there another way to run the file other than using subprocess module ?
subprocess.call(["python", "script2.py"]) waits for the sub-process to finish.
Just use Popen instead:
proc = subprocess.Popen(["python", "script2.py"])
You can later do proc.poll() to see whether it is finished or not, or proc.wait() to wait for it to finish (as call does), or just forget about it and do other things instead.
BTW, you might want to ensure that the same python is called, and that the OS can find it, by using sys.executable instead of just "python":
subprocess.Popen([sys.executable, "script2.py"])

using subprocess.call to read output of c executable print statement realtime

I have a c executable which gets data from a iot hardware and print information on console using printf. I want to run this executable from python which I am able to do so using subprocess.call in following way
subprocess.call(["demoProgram", "poll"])
and print the output to console. But I need to capture this output(printf) using my python code to process information further in real time. How can I capture this output using subprocess in real time?
The following opens a subprocess and creates an iterator from the output.
import subprocess
import sys
proc = subprocess.Popen(['ping','google.com'], stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline, ''):
print(line) # process line-by-line
This solution was modified from the answer to a similar question.
if you're using python 2x
have a look at the commands module
import commands
output=commands.getoutput("gcc demoProgram.c") #command to be executed
print output
for python3x
use the subprocess module
import subprocess
output=subprocess.getoutput("gcc demoProgram.c") #command to be executed
print output

execv multiple executables in single python script?

From what I can tell, execv overtakes the current process, and once the called executable finishes, the program terminates. I want to call execv multiple times within the same script, but because of this, that cannot be done.
Is there an alternative to execv that runs within the current process (i.e. prints to same stdout) and won't terminate my program? If so, what is it?
Yes, use subprocess.
os.execv* is not approporiate for your task, from doc:
These functions all execute a new program, replacing the current
process; they do not return. On Unix, the new executable is loaded
into the current process, and will have the same process id as the
caller.
So, as you want the external exe to print to the same output, this is what you might do:
import subprocess
output = subprocess.check_output(['your_exe', 'arg1'])
By default, check_output() only returns output written to standard output. If you want both standard output and error collected, use the stderr argument.
output = subprocess.check_output(['your_exe', 'arg1'], stderr=subprocess.STDOUT)
The subprocess module in the stdlib is the best way to create processes.

Categories

Resources