Reputation: 816
I am using a script written in Python that uses the argparse module to get it's arguments from command line. I try to modify this file as less as possible as various people work on it.
Ex: script is called CLscript.py and I call it with
python CLscript.py -option1 arg1 -flag1 -option2 arg2
But I'm facing the case where I would like to automate things one level higher and automatically launch this script with wide range of script-generated arguments.
I would like to keep using all the existing organisation of options and flags available in this script.
For example, when I run CLscript.py from topLevelScript.py through :
subprocess.call("python CLscript.py -option1 arg1 -flag1 -option2 arg2")
,and I see from the output that something is going wrong, I stop the execution topLevelScript.py, but CLscript.py continue to run independently in another python process that I Have to kill manually. I cannot neither launch topLevelScript.py in debug mode to stop at a breakpoint in CLscript.py.
I would like to do this all from inside python, without building a command line string and launching CLscript.py with a subprocess. Every call would remains attached to the same original launch, just like a function call, and not creating multiple python threads like it would do with a subprocess.call() .
Something like passing a list of string with options, flags and arguments somehow to the script maybe?
Is there something like
import CLscript.py
CLsimulator(CLscript,["-option1",arg1,"-flag1","-option2",arg2])
Upvotes: 0
Views: 199
Reputation: 11290
First of all, use http://docs.python.org/2/library/subprocess.html#subprocess.Popen and not subprocess.call()
:
import subprocess
child = subprocess.Popen(
['python', 'CLscript.py', '-option1', 'arg1', '-flag1', '-option2', 'arg2'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
Please notice that as the first argument you pass an array of strings
just like you want.
Secondly redirection of standard file descriptors will be important. See http://docs.python.org/2/library/subprocess.html#subprocess.PIPE.
Now you have child
variable which holds instance of Popen
class.
What you can do with this instance?
# Check if child is terminated and possibly get the returncode
child.poll()
# Write to child's standard input by a file-like object accessible with
child.stdin
# Read child's standard output and standard error by file-like objects accesible with
child.stdout
child.stderr
You said you wanted to detect if something goes wrong in the child process from it's output.
Don't you find stdout
and stderr
quite useful for this case?
Now you wanted to terminate the child if you detected that something went wrong.
child.kill()
child.terminate()
child.send_signal(signal)
If in the end you are sure that everything went well but you want to let child finalize normally, you should use
child.wait()
or even better
child.communicate()
because communicate
will handle lots of output properly.
Good luck!
Upvotes: 1
Reputation: 3158
Would something like this work? Extract most of your code into a new function that expects arguments similar to the ones you send in via the command line. Then write a new function that gathers the command line arguments and sends them to the first function ...
def main(foo, bar):
a = foo + bar
print a
def from_command_line():
foo, bar = get_command_line_args()
main(foo, bar)
if __name__ == "__main__":
from_command_line()
Then your other scripts can just call the main function.
Upvotes: 1