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
Related
I have written a C code where I have converted one file format to another file format. 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.
I am trying like :
import subprocess
import sys
filestem = sys.argv[1];
subprocess.run(['/home/dev/executable_file', filestem , 'outputfile'])
But it is unable to create the outputfile. I think some thing should be added to solve the > issue. But unable to figure out. Please help.
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!
I am creating a python script for running the linux command which is " snmpwalk -v2c -c aL1walsh0aL <> ifInError"
I need to execute the command for multiple hosts IP which is in hostname.txt file.
When i run the python script below i am getting the output for "snmpwalk -v2c -c aL1walsh0aL" and the error for hostname not defined.
So basically my complete command is not executing which gives me correct output.
But i need the output for eg: snmpwalk -v2c -c aL1walsh0aL 10.0.0.1 ifInError
My python script:
import subprocess
with open("hostname.txt","rw") as f:
for line in f.readlines():
subprocess.Popen(['snmpwalk', '-v2c','-c',line],stdout=subprocess.PIPE)
f.close()
import subprocess
with open("mac.txt","rw") as f: # mac.txt is the text file with mac address
for line in f.readlines():
print (line)
print ("************")
process=subprocess.Popen(['macsearch', line],stdout=subprocess.PIPE)
out=process.communicate() """ using process.communicate to save the
output."""
for o in out:
print o
print ('\n')
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)
I'm trying to execute a perl script within another python script. My code is as below:
command = "/path/to/perl/script/" + "script.pl"
input = "< " + "/path/to/file1/" + sys.argv[1] + " >"
output = "/path/to/file2/" + sys.argv[1]
subprocess.Popen(["perl", command, "/path/to/file1/", input, output])
When execute the python script, it returned:
No info key.
All path leading to the perl script as well as files are correct.
My perl script is executed with command:
perl script.pl /path/to/file1/ < input > output
Any advice on this is much appreciate.
The analog of the shell command:
#!/usr/bin/env python
from subprocess import check_call
check_call("perl script.pl /path/to/file1/ < input > output", shell=True)
is:
#!/usr/bin/env python
from subprocess import check_call
with open('input', 'rb', 0) as input_file, \
open('output', 'wb', 0) as output_file:
check_call(["perl", "script.pl", "/path/to/file1/"],
stdin=input_file, stdout=output_file)
To avoid the verbose code, you could use plumbum to emulate a shell pipeline:
#!/usr/bin/env python
from plumbum.cmd import perl $ pip install plumbum
((perl["script.pl", "/path/to/file1"] < "input") > "output")()
Note: Only the code example with shell=True runs the shell. The 2nd and 3rd examples do not use shell.
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