parse command line arguments not reading all arguments? - python

So, I came across the getopt module to parse command line args, although I can't make any sense of the docs. For whatever reason, I cannot figure out why this isn't seeing my --domain example.com argument..
$ ./httpdsetup.py -a -u zack --domain example.com
[('-a', ''), ('-u', '')]
I printed out what gets dumped into opts to see what it saw. The code below is just about an exact duplicate from the documentation site.
def main(argv):
import getopt
try:
opts, args = getopt.getopt(argv, "h:al:ud:v", ["user=", "apache", "lighttpd", "dir=", "domain=", "vhost="])
except getopt.GetoptError:
print_usage()
sys.exit(2)
username = ''
directory = ''
domain = ''
httpd = 'apache'
print(opts)
for opt, arg in opts:
if opt == '-h':
print_usage()
sys.exit()
elif opt in ('-u', '--username'):
username = arg
elif opt in ('-d', '--dir'):
directory = arg
elif opt in ('-v', '--domain', '--vhost'):
domain = arg
elif opt in ('-a', '--apache'):
httpd = 'apache'
elif opt in ('-l', '--lighttpd'):
httpd = 'lighttpd'
else:
print_usage()
sys.exit()
if httpd == 'apache':
create_apache_vhost(domain, directory, username)
elif httpd == 'lighttpd':
create_lighty_vhost(domain, directory, username)
if __name__ == '__main__':
main(sys.argv[1:])

I prefer argparse. Python documention here.
It's in Python >=2.7 and >=3.2, but not in Python 3.0 and 3.1. If it's missing in your install, just copy the single file from here to where your script is, or into your Python install.
Here's something close to your example with argparse:
#!/usr/bin/env python3
import sys
def create_apache_vhost(*args, **kwargs):
pass
def create_lighty_vhost(*args, **kwargs):
pass
def main(argv):
import argparse
parser = argparse.ArgumentParser(description="Some server",
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--username', type=str)
parser.add_argument('-u', dest='username', type=str)
parser.add_argument('--apache', dest='httpd', action='store_const', const='apache')
parser.add_argument('-a', dest='httpd', action='store_const', const='apache')
parser.add_argument('--lighthttpd', dest='httpd', action='store_const', const='lighthttpd')
parser.add_argument('-l', dest='httpd', action='store_const', const='lighthttpd')
parser.add_argument('--domain', type=str)
parser.add_argument('--vhost', type=str)
parser.add_argument('-v', dest='domain', type=str)
parser.add_argument('--dir', dest='directory', type=str)
parser.add_argument('-d', dest='directory', type=str)
defaults = {
'httpd': 'apache',
}
parser.set_defaults(**defaults)
args = parser.parse_args(args=argv)
print(args)
if args.httpd == 'apache':
create_apache_vhost(args.domain, args.directory, args.username)
elif args.httpd == 'lighttpd':
create_lighty_vhost(args.domain, args.directory, args.username)
if __name__ == '__main__':
main(sys.argv[1:])

Related

Pass multiple argument from command line

i trying with
import sys, getopt
def main(argv):
inputfile = ''
outputfile = ''
dpd = ''
opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile=","dpd="])
print(opts)
for opt, arg in opts:
print(opt)
if opt == '-h':
print ('test.py -i <inputfile> -o <outputfile>')
sys.exit()
elif opt in ("-i", "--ifile"):
inputfile = arg
elif opt in ("-o", "--ofile"):
outputfile = arg
elif opt in ("-d","--dpd"):
dpd = arg
print ('Input file is ', inputfile)
print ('Output file is ', outputfile)
print ('DPD', dpd)
if __name__ == "__main__":
main(sys.argv[1:])
and run with python3 demo.py -i 65 -o ale -d 45 but it's give error
getopt.GetoptError: option -d not recognized
and i want to pass 6 pass argument how can i do this??
You should be using argparse, which is simpler and much more powerful than getopt.
But the problem is that you forgot to declare -d as an option:
opts, args = getopt.getopt(argv,"hi:o:d:",["ifile=","ofile=","dpd="])
There is a built-in library for this in Python. I strongly recommend that you use it - you get a lot of stuff out of the box and the errors will be more informative.
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-d', '--dpd')
>>> args = parser.parse_args(['-d', 'bla'])
>>> args.dpd
'bla'
If you just add the rest of your arguments your program becomes much simpler:
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--ifile')
parser.add_argument('-o', '--ofile')
parser.add_argument('-d', '--dpd')
print(f'dpd: {args.dpd}')
print(f'input: {args.ifile}')
print(f'output: {args.ofile}')
You get the help arg with autoexit out of the box too.
You can also specify which parameters are required and which are optional, set default values and a lot more.

python try...except in handling argument from user input

my python file would read two files from command line using argparse.
I want to use 'try...except...' to handle incorrect user input, like non-exist file and incorrect command:
for example, I use '-f' to open file, then '-g' is incorrect command.
my codes are:
> parser = argparse.ArgumentParser(description = "Handle with input
files")
parser.add_argument('-m', dest = "model", type=argparse.FileType('r'))
parser.add_argument('-t', dest = "test", type=argparse.FileType('r'))
parser.add_argument('-d', dest = "permute",type=argparse.FileType('r'))
args = parser.parse_args()
# Parse file names from command line
model_file = open(args.model.name)
test_file = open(args.test.name)
decoy_file = open(args.permute.name)
I try to implement 'try...except' in my code but failed. Here is what I did:
> parser = argparse.ArgumentParser(description = "Handle with input
files")
parser.add_argument('-m', dest = "model", type=argparse.FileType('r'))
parser.add_argument('-t', dest = "test", type=argparse.FileType('r'))
parser.add_argument('-d', dest = "permute",type=argparse.FileType('r'))
args = parser.parse_args()
# Parse file names from command line
try:
model_file = open(args.model.name)
test_file = open(args.test.name)
decoy_file = open(args.permute.name)
except IOError:
print('Wrong file name')
I would suggest adding something like this to make sure all arguments are there. Also argparse.FileType('r') will already open the file (meaning you can do something like args.model.readlines()).
if not all([args.model, args.test, args.permute]):
print("All Arguments are required")
exit(1)
Firstly the error happend at args = parser.parse_args() when it parse your command param.
As we can see from argparse's origin code:
...
def parse_args(self, args=None, namespace=None):
args, argv = self.parse_known_args(args, namespace)
if argv:
msg = _('unrecognized arguments: %s')
self.error(msg % ' '.join(argv))
return args
...
def error(self, message):
"""error(message: string)
Prints a usage message incorporating the message to stderr and
exits.
If you override this in a subclass, it should not return -- it
should either exit or raise an exception.
"""
self.print_usage(_sys.stderr)
args = {'prog': self.prog, 'message': message}
self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
# exit here ,that's why can not catch the exception
So when you input incorrectly, like what you mentioned above, like non-exist file or incorrect command , it will call error function in the end, and exit the thread, that's why you cannot catch a exception by try .. except synax.
If you want to catch the exception, you can inherit the main class ArgumentParser, and rewrite the method error. you can take my codes as reference:
import argparse
import sys as _sys
from argparse import ArgumentParser
class ArgumentParserSub(ArgumentParser):
def error(self, message):
self.print_usage(_sys.stderr)
args = {'prog': self.prog, 'message': message}
raise Exception(('error: %(message)s\n') % args)
parser = ArgumentParserSub(description = "Handle with input files")
parser.add_argument('-m', dest = "model", type=argparse.FileType('r'))
parser.add_argument('-t', dest = "test", type=argparse.FileType('r'))
parser.add_argument('-d', dest = "permute",type=argparse.FileType('r'))
try:
args = parser.parse_args()
# Parse file names from command line
model_file = open(args.model.name)
test_file = open(args.test.name)
decoy_file = open(args.permute.name)
except Exception as e:
print(e)
print('Wrong file name')
If you don't want the parser to catch and exit bad files, open the files yourself. Just ask the parser for names, not open files.
parser = argparse.ArgumentParser(description = "Handle with input files")
parser.add_argument('-m', dest = "model") # no type
parser.add_argument('-t', dest = "test")
parser.add_argument('-d', dest = "permute")
args = parser.parse_args()
# print(args) # good idea when debugging
# Open file names from command line
try:
model_file = open(args.model)
test_file = open(args.test)
decoy_file = open(args.permute)
except IOError:
print('Wrong file name')

New to python. Need help to understand code

Hello I am new to python just started . Would be glad if someone can help me to understand this piece of code.
#!/usr/bin/python
import sys, getopt
def main(argv):
inputfile = ''
outputfile = ''
try:
opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
except getopt.GetoptError:
print 'test.py -i <inputfile> -o <outputfile>'
sys.exit(2)
for opt, arg in opts:
if opt == '-h':
print 'test.py -i <inputfile> -o <outputfile>'
sys.exit()
elif opt in ("-i", "--ifile"):
inputfile = arg
elif opt in ("-o", "--ofile"):
outputfile = arg
print 'Input file is "', inputfile
print 'Output file is "', outputfile
if __name__ == "__main__":
main(sys.argv[1:])
To the best of my ability, please find my comments (# comments) below:
#!/usr/bin/python
# importing libraries
import sys, getopt
def main(argv):
# defining empty string variables
inputfile = ''
outputfile = ''
# try/except block. Try this code, if it fails, handle it
try:
# looks like you are parsing command line arguments
opts, args = getopt.getopt(argv,"hi:o:",["ifile=","ofile="])
except getopt.GetoptError:
print 'test.py -i <inputfile> -o <outputfile>'
sys.exit(2)
#iterate through the cmd line arguments
for opt, arg in opts:
# of option is -h, do this (same with the following)
if opt == '-h':
print 'test.py -i <inputfile> -o <outputfile>'
sys.exit()
elif opt in ("-i", "--ifile"):
inputfile = arg
elif opt in ("-o", "--ofile"):
outputfile = arg
print 'Input file is "', inputfile
print 'Output file is "', outputfile
# python main function
if __name__ == "__main__":
# call method main and pass the cmd line arguments
main(sys.argv[1:])

Python Arguments, Required 1 Argument

I am working on a zip file password cracker, and I need a brute-force option. I have the basic code for it written out, but I am not sure of how to use an argument to make it work. How can I write an argument to make this work?
import optparse
import zipfile
import argparse
from threading import Thread
parser = argparse.ArgumentParser()
parser.add_argument("-b", "--brute")
def extract_zip(zFile, password):
try:
password_encoded = bytes(password.encode('utf-8'))
zFile.setpassword(password_encoded)
zFile.testzip()
print ("[+] Password Found: " + password + '\n')
except:
pass
def Main():
parser = optparse.OptionParser("useage &prog "+\
"-f <zipfile> -d <dictionary> / -b <brute force>")
parser.add_option('-f', dest='zname', type='string',\
help='specify zip file')
parser.add_option('-d', dest='dname', type='string',\
help='specify dictionary file')
parser.add_option('-b', dest='bname', type='string',\
help='specify brute force')
(options, arg) = parser.parse_args()
if (options.zname == None) | (options.dname == None) | (options.bname == None):
print (parser.usage)
exit(0)
else:
zname = options.zname
dname = options.dname
bname = options.bname
zFile = zipfile.ZipFile(zname)
passFile = open(dname)
brute = open(bname)
for line in passFile.readlines():
password = line.strip('\n')
t = Thread(target=extract_zip, args=(zFile, password))
t.start()
if args.brute:
characters = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
for length in range(1, int(args.brute)):
to_attempt = product(characters, repeat=length)
t = Thread(target=extract_zip, args=(zFile, password))
t.start()
if __name__ == '__main__':
Main()

Arguments for batch size not being captured. Any idea?

I do have following script to capture the command line arguments. Third option for batch size is not being set any idea ?
FYI : Only input & ouput file options are required parameter. Batch is optional.
import sys, getopt
import os
try:
opts, args = getopt.getopt(argv,"hi:o:b",["ifile=","ofile=","bsize="])
except getopt.GetoptError:
print 'file.py -i <inputfile> -o <outputfile> -b<batchsize>[default=20000000]'
sys.exit(2)
for opt, arg in opts:
print opt
if opt == '-h':
print 'file.py -i <inputfile> -o <outputfile> -b<batchsize>[default=20000000]'
sys.exit()
elif opt in ("-i", "--ifile"):
inputFile = arg
elif opt in ("-o", "--ofile"):
outputFile = arg
elif opt in ("-b", "--bsize"):
print "Another option %s" % opt
batchsize = arg
You have several problems with this script including indent errors and failing to initialize settings first... But let's assume you just copy/pasted it incorrectly.
The answer is that you are missing a ":" after the "b" in your getopt arguments.
This line:
opts, args = getopt.getopt(argv,"hi:o:b",["ifile=","ofile=","bsize="])
Should actually be:
opts, args = getopt.getopt(argv,"hi:o:b:",["ifile=","ofile=","bsize="])
If you don't mind, I would recommend argparse. It is better usably and not as clunky as getopts.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--ifile", required=True)
parser.add_argument("-o", "--ofile", required=True)
parser.add_argument("-b", "--bsize", type=int, default=20000000)
parser.parse_args()
input_file = parser.input
etc.

Categories