passing argument from python to subprocess.popen - python

I have this code:
from subprocess import Popen
link="abc"
theproc = Popen([sys.executable, "p1.py",link])
I want to send the variable "link" to p1.py,
and p1.py will print it.
something like this. here is p1.py:
print "in p1.py link is "+ link
How can I do that?

I'm assuming python refers to Python 2.x on your system.
Retrieve the command line argument in p1.py using sys.argv:
import sys
if not len(sys.argv) > 1:
print "Expecting link argument."
else:
print "in p1.py link is " + sys.argv[1]
There's a function subprocess.check_output that is easier to use if you only want to call a program and retrieve its output:
from subprocess import check_output
output = check_output(["python", "p1.py", "SOME_URL"])
print "p1.py returned the following output:\n'{}'".format(output)
Example output:
$ python call_p1.py
p1.py returned the following output:
'in p1.py link is SOME_URL
'

You have to parse the command line arguments in your p1.py to get it in a variable:
import sys
try:
link = sys.argv[1]
except IndexError:
print 'argument missing'
sys.exit(1)

Related

Get result to python variable after executing R script

i am executing a r script from python and i want the output to be available in the python variable. how can i do that?
python script:
import subprocess
def runR(id, lat, long):
value = subprocess.popen("C:/R/R-3.2.0/bin/Rscript E:/Personal/python/script.R --args "+id+" "+lat+" "+long , shell=True)
print value
R script :
a = "Hello";
I want Hello to be availabe on the python variable value.
You could use rpy2:
import rpy2.robjects as robjects
robjects.r('''
a = "Hello";
''')
a = robjects.r['a']
As an alternative, you could rewrite your R script so that it would dump its result to stdout in some well-known format such as json, then run it using subprocess module, and parse the result:
#!/usr/bin/env python
import json
import subprocess
id, lat, long = 1, 40, 74
out = subprocess.check_output(r"C:\R\R-3.2.0\bin\Rscript.exe "
r"E:\path\to\script.R --args "
"{id} {lat} {long}".format(**vars()))
data = json.loads(out.decode('utf-8'))
Note: no need to use shell=True on Windows if you use the full path to the executable here.
You can modify the following example by your need.
a.py:
print 'hello'
b.py:
import subprocess
result = subprocess.check_output(["python", "a.py"])
print result.strip() + 'world'
Output of b.py:
helloworld

excecute a python script with argument in another python script

I have a python script that should be called with two argument:
$ python ./script.py arg1 arg2
The content of this script is sth like this:
#!/usr/bin/python
import sys
import commands
if len(sys.argv) != 3:
print 'Usage: python %s <IP1> <IP2>' % (sys.argv[0])
sys.exit()
.
.
.
with open('/tmp/file.txt', 'r+') as f:
for line in f:
execfile("script.py --host $line")
But this is not correct, when I use this type of execfile this is wrong because:
it says the syntax is not correct..The correct form is execfile("script.py") but I have one argument and also I have variable line from my for loop
I want to run script.py with --host and variable that should be for each line from file.txt
How can I do that?
Thank you
execfile run a python script by loading it, not as a script. You should use os.system or subprocess.Popen for that.
for instance:
#!/usr/bin/python
import sys
import commands
import os # Change here!!
if len(sys.argv) != 3:
print 'Usage: python %s <IP1> <IP2>' % (sys.argv[0])
sys.exit()
.
.
.
with open('/tmp/file.txt', 'r+') as f:
for line in f:
os.system("script.py --host %s" % line)
run the command with subprocess will allows you store the standar and error ouput from the command.
Using subprocess:
import subprocess
with open('/tmp/file.txt', 'r+') as f:
for line in f:
proc = subprocess.Popen(["script.py", "--host", line], sdtout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate() # out: stadar output, err: error output

Parsing command line parameters

As an example of my problem consider the following situation:
A user launches a program from command line with a syntax similar to this
python prog.py "hi there" hi=Hello there=World!
The output of the program is "Hello World!".
My question refers to the part of parsing the arguments. How can I save the information contained in the "hi=Hello there=World!" part in order to use it? From there I should be able to do something with it.
I don't have the slightest idea of what the parameters are going to be so the solution needs to be as generic as possible.
you have to do something like this... save this as "argtest.py":
import sys
def main(x):
print(x)
if __name__ == "__main__":
print sys.argv #notice this is whatever you put in the arguments
print sys.argv[0] # this is the name of the file you used
main(sys.argv[1])
this will pass the first arg into main()
so if you are running from command line
python argtest.py hello
your output will be
hello
in your main() you would of course define whatever you want to do with the argument
personally i do my parsing in under the if __name__=="__main__": line usually something like arguments = [x.split('=') for x in sys.argv[1:]] #if you want to seperate arguments like "pie=apple fart=stinky"
sys.argv is a list of whatever you put after python argtest.py space seperated
for example if you do python argtest.py apple pie comma poop
sys.argv[1] == 'apple'
sys.argv[2] == 'pie'
sys.argv[3] == 'comma'
sys.argv[4] == 'poop'
Using docopt
install docopt:
$ pip install docopt
Write the code of prog.py:
"""
Usage:
prog.py <greeting> <name>
"""
if __name__ == "__main__":
from docopt import docopt
args = docopt(__doc__)
print args
print "------"
name = args["<name>"]
greeting = args["<greeting>"]
print "{greeting} {name}!".format(greeting=greeting, name=name)
Use it:
First see usage instructions:
$ python prog.py
Usage:
prog.py <greeting> <name>
Then use it:
$ python prog.py Ola Mundi
{'<greeting>': 'Ola',
'<name>': 'Mundi'}
------
Ola Mundi!
I ended up using simple string processing:
import sys
entry = {}
for i in sys.argv[1:]:
pos = i.find("=")
entry[i[:pos]] = i[pos+1:]

executing a python script from another python script

I have a script a.py :
#!/usr/bin/env python
def foo(arg1, arg2):
return int(arg1) + int(arg2)
if __name__ == "__main__":
import sys
print foo(sys.argv[1], sys.argv[2])`
I now want to make a script that can run the first script and write the output of a.py to a file with some arguments as well. I want to make the automate_output(src,arglist) generate some kind of an output that I can write to the outfile :
import sys
def automate_output(src, arglist):
return ""
def print_to_file (src, outfile, arglist):
print "printing to file %s" %(outfile)
out = open(outfile, 'w')
s = open(src, 'r')
for line in s:
out.write(line)
s.close()
out.write(" \"\"\"\n Run time example: \n")
out.write(automate(src, arglist))
out.write(" \"\"\"\n")
out.close()
try:
src = sys.argv[1]
outfile = sys.argv[2]
arglist = sys.argv[3:]
automate(src, arglist)
print_to_file(src,outfile,arglist)
except:
print "error"
#print "usage : python automate_runtime.py scriptname outfile args"
I have tried searching around, but so far I do not understand how to pass arguments by using os.system with arguments. I have also tried doing :
import a
a.main()
There I get a NameError: name 'main' is not defined
Update :
I researched some more and found subprocess and I'm quite close to cracking it now it seems.
The following code does work, but I would like to pass args instead of manually passing '2' and '3'
src = 'bar.py'
args = ('2' , '3')
proc = subprocess.Popen(['python', src, '2' , '3'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print proc.communicate()[0]
This is not a function, it's an if statement:
if __name__ == "__main__":
...
If you want a main function, define one:
import sys
def main():
print foo(sys.argv[1], sys.argv[2])`
Then just call it if you need to:
if __name__ == "__main__":
main()
a.main() has nothing to do with if __name__=="__main__" block. The former calls a function named main() from a module, the latter executes its block if current module name is __main__ i.e., when a module is called as a script.
#!/usr/bin/env python
# a.py
def func():
print repr(__name__)
if __name__=="__main__":
print "as a script",
func()
Compare a module executed as a script and a function called from the imported module:
$ python a.py
as a script '__main__'
$ python -c "import a; print 'via import',; a.func()"
via import 'a'
See section Modules in the Python tutorial.
To get output from the subprocess you could use subprocess.check_output() function:
import sys
from subprocess import check_output as qx
args = ['2', '3']
output = qx([sys.executable, 'bar.py'] + args)
print output

How can I check with doctest that a program produced certain output?

In one of my functions I'm calling an external program, using subprocess.check_call, which will produce output. How could I use doctest to make sure the output it's producing is the one I'm expecting?
Maybe this can help:
import sys
import tempfile
import subprocess
def example(output):
r""" Do something ...
>>> output = example('Processing file ...')
>>> print output # doctest:+ELLIPSIS
'Processing file ...'
Check how many file was processed.
>>> [line.startswith('Processing file')
... for line in output.splitlines()].count(True)
1
"""
cmd = "print '%s'" % (output, )
with tempfile.TemporaryFile() as output:
subprocess.check_call([sys.executable, '-c', cmd], stdout=output)
output.seek(0)
res = output.read()
return res
if __name__ == '__main__':
import doctest
doctest.testmod()
As you can see i used the argument stdout of the subprocess.check_call function so to be able to get the output of the command , beside that if you are not using the stdout argument (which i assume that is your case) i think it very hard to capture the command output.
Hope this was hopeful :)

Categories

Resources