Python command in python script from another python script - python

I read already this What is the best way to call a Python script from another Python script?
In my case I don't want to call another python script in a python script, but I want to call for example the ssylze.py with the specific options
$ python sslyze.py --regular www.target1.com
like consider in https://code.google.com/p/sslyze/wiki/QuickStart
So I have script test1.py and in that script I would like to use
sslyze.py --regular www.target1.com
how I do that?

Not sure if I've unscrambled the code from your comment ok and whether this is what you are trying to do. As I don't know what sslyze.py is doing I haven't tested it. However your problem might be due to not waiting for each subprocess to terminate:
import subprocess
with open("ip.txt", "r") as file_in:
fname = "scan.txt"
with open("scan.txt","w") as file_out:
for line in file_in:
process = subprocess.Popen(["python", "sslyze.py", "--regular", line], stdout=subprocess.PIPE)
file_out.write(process.communicate()) # you might need to append \n to whatever you write

You can use the argparse module:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-r", "--regular", action="store")
args = parser.parse_args()
print vars(args)["regular"]
Running the above snippet (asd.py) with python asd.py --regular www.target1.com will print "www.target1.com". Hope this provides enough of an example to be helpful.

Related

How to invoke a specific shell with python?

I want to invoke a specific command shell in python to execute some scripts. For exemple, in R, I use:
system2(os_shell = "C:/Program Files (x86)/pgAdmin III/1.18/pg_dump.exe", args = "very long argument")
Thanks to this code, I can backup my Postgresql's tables with a for loop.
Problem: I didn't find an equivalent in Python.
If you just want to execute a application with args in a shell you can do that very easily with os.system
import os
os.system("'C:/Program Files (x86)/pgAdmin III/1.18/pg_dump.exe' very long argument")
Tho I would recommend subprocess.call or subprocess.run
import subprocess
subprocess.call(["'C:/Program Files (x86)/pgAdmin III/1.18/pg_dump.exe'", "argument1", "argument2"]) #and you can add as many arguments you want

Forward a shell command using python

So to be more precise, what I am trying to do is :
read a full shell command as argument of my python script like : python myPythonScript.py ls -Fl
Call that command within my python script when I'd like to (Make some loops on some folders and apply the command etc ...)
I tried this :
import subprocess
from optparse import OptionParser
from subprocess import call
def execCommand(cmd):
call(cmd)
if __name__ == '__main__':
parser = OptionParser()
(options,args) = parser.parse_args()
print args
execCommand(args)
The result is that now I can do python myPythonScript.py ls , but I don't know how to add options. I know I can use parser.add_option , but don't know how to make it work for all options as I don't want to make only specific options available, but all possible options depending on the command I am running.
Can I use something like parser.add_option('-*') ? How can I parse the options then and call the command with its options ?
EDIT
I need my program to parse all type of commands passed as argument : python myScript.py ls -Fl , python myScript.py git pull, python myScript rm -rf * etc ...
OptionParser is useful when your own program wants to process the arguments: it helps you turn string arguments into booleans or integers or list items or whatever. In your case, you just want to pass the arguments on to the program you're invoking, so don't bother with OptionParser. Just pass the arguments as given in sys.argv.
subprocess.call(sys.argv[1:])
Depending on how much your program depends on command line arguments, you can go with simple route.
Simple way of reading command line arguments
Use sys to obtain all the arguments to python command line.
import sys
print sys.argv[1:]
Then you can use subprocess to execute it.
from subprocess import call
# e.g. call(["ls", "-l"])
call(sys.argv[1:])
This sample below works fine for me.
import sys
from subprocess import call
print(sys.argv[1:])
call(sys.argv[1:])

python testing strategy to develop and auto-grader

I have a list of input files and an expected output file, I want to write an auto-grader that does the job of accepting a python program, running it on the input files, and comparing its output to the output file. The approach I have used is to use the os module of python to run the program using os.system('python program.py > actual.out') and then perform a diff between the output and expected.out again using os.system().
The problem which I am currently facing is reading the input from the file because the program which is given is reading from the console. So, how should I redirect the input from a file such that it is readable by sys.stdin in program.py.
import os
def grade(program_py_file_handler,input_dir,output_dir):
#create temporary file for program.py using program_py_file_handler
#one by one read all files from input_dir
#run program.py using os.system generating a temp file
#do diff be temp file and expected file
Is there a better way to perform a diff without using the diff command?
To redirect output from program.py to a file I used python program.py>tem.out. What equivalent should I use to redirect an input file to progam.py such that wherever I have used sys.stdin in program.py it will instead read from the passed file? (Modifying program.py is not an option.)
You can be doing everything using builtin modules in Python 3.3+, since you are effectively spinning up a subprocess and doing a diff on the expected output. Simple minimum example:
check.py
import sys
from subprocess import check_output
from difflib import ndiff
def split(s):
return s.splitlines(keepends=True)
def check(program_name, expected):
output = check_output([sys.executable, program_name]).decode('utf8')
diff = ndiff(split(output), split(expected))
print(''.join(diff), end="")
def main():
check('hello.py', 'Good Morning!\n')
if __name__ == '__main__':
main()
hello.py
print('Good Evening!')
Example run
$ python check.py
- Good Evening!
? ^^^
+ Good Morning!
? ^^^
Modify as you see fit, with other methods/functions in the libraries linked. If you need stdin for the subprocess you probably will need to create Popen object and call communicate, but please read documentations first for future reference.

Pass output of a script to another script using sys.argv

I'm trying to take the output of one script and pass it using sys.argv to my python script.
The question I have is whether there's a way to accomplish this similar to
python runfile.py $(node parse.js)
For testing, runfile.py just consists of:
import sys
print sys.argv
But, as you might've guessed, that just logs ['runfile.py'].
Am I totally barking up the wrong tree here? If so, can someone explain or link to an explanation of how to pass the output of, say, a javascript file to a python script?
Edit: is there a way to mark the $(node parse.js) part as a separate argument that should be evaluated?
Instead of passing the output of node parse.js to your python script via command line arguments (sys.argv) you could use stdin and unix pipes:
node parse.js | python runfile.py
And edit runfile.py to look like:
import sys
print sys.stdin

call program with arguments

i would like to start a python file (.py) with arguments and receive the output of it after it is finished. i have already heard about "popen" and "subprocess.call" but i could not find any tutorials how to use them
does anyone know a good tutorial?
You don't need them ; just launch your file as a program giving argument like
./main.py arg1 arg2 arg3 >some_file
(for that your file must begin with something like #!/usr/bin/env python)
Using sys module you can access them :
arg1 = sys.argv[1]
arg2 = sys.argv[2]
arg3 = sys.argv[3]
i would like to start a python file (.py) with arguments and receive the output of it after it is finished.
Step 1. Don't use subprocess. You're doing it wrong.
Step 2. Read the Python file you want to run. Let's call it runme.py.
Step 3. Read it again. If it's competently written, there is a block of code that starts if __name__ == "__main__":. What follows is the "external interface" to that file. Since you provided no information in the question, I'll assume it looks like this.
if __name__ == "__main__":
main()
Step 4. Read the "main" function invoked by the calling script. Since you provided no information, I'll assume it looks like this.
def main():
options, args = parse_options()
for name in args:
process( options, file )
Keep reading to be sure you see how parse_options and process work. I'll assume parse_options uses optparse.
Step 5. Write your "calling" script.
import runme
import sys
import optparse
options = options= optparse.Values({'this':'that','option':'arg','flag':True})
with open( "theoutput.out", "w" ) as results:
sys.stdout= results
for name in ('some', 'list', 'of', 'arguments' ):
runme.process( options, name )
This is the correct way to run a Python file from within Python.
Actually figure out the interface for the thing you want to run. And run it.
runme.py
print 'catch me'
main.py
import sys
from StringIO import StringIO
new_out = StringIO()
old_out = sys.stdout
sys.stdout = new_out
import runme
sys.stdout = old_out
new_out.seek(0)
print new_out.read()
and...
$ python main.py
catch me
Unless you mean you want to start the Python file from within Python? In which case it's even nicer:
import nameOfPythonFile

Categories