Python, argument parameter error with sys module - python

I am trying to get arguments in python with the sys module.
Here my code:
import sys
import os
path = sys.argv[0]
argument = sys.argv[1]
print("Hello, Temal Script installed.")
if argument == "-h":
os.system("cls")
print("Available comamnds:\n-h = help\n-i = information\n-v = version")
if argument == "-i":
os.system("cls")
print("This is a script written by Temal")
if argument == "-v":
os.system("cls")
print("Version: 1.0")
If I enter in the cmd "main.py -h" it works great. But if I enter only "main.py" it prints me out an error:
Traceback (most recent call last):
File "C:\Windows\cmd.py", line 5, in <module>
argument = sys.argv[1]
IndexError: list index out of range
I know why i get this error, because in the list will be only one item (the path) because i dont enter a second argument. But how can I do that the script ignores this error if no second argument is set? If someone enters main.py without an argument I only want to print out this text: Hello, Temal Script installed.
Or maybe is there something like in PHP "isset"?
I am also new to this topic so please answer simple and not complicated.
Thanks!

Need to check the length of the sys.argv variable.
import sys
import os
path = sys.argv[0]
if len(sys.argv) > 1:
argument = sys.argv[1]
print("Hello, Temal Script installed.")
if argument == "-h":
os.system("cls")
print("Available comamnds:\n-h = help\n-i = information\n-v = version")
elif argument == "-i":
os.system("cls")
print("This is a script written by Temal")
elif argument == "-v":
os.system("cls")
print("Version: 1.0")
Also, look at argparse module.
import argparse
import os
parser = argparse.ArgumentParser(description="My App")
parser.add_argument('-i', '--info', action='store_true',
help="show information")
parser.add_argument('-v', '--version', action='store_true',
help="show version")
args = parser.parse_args()
if args.info:
os.system("cls")
print("This is a script written by Temal")
elif args.version:
os.system("cls")
print("Version: 1.0")
Run main.py -h outputs:
usage: help.py [-h] [-i] [-v]
My App
optional arguments:
-h, --help show this help message and exit
-i, --info show information
-v, --version show version

Related

Using the subprocess library: error: unrecognized arguments

So essentially I have 15 or so scripts that can connect to various networking devices using an SSH library. I want to create one top-level python file that can run other python scripts so the user can decide which scripts they want to run. I have been advised to use the subprocess library and this seems to make the most sense for what I want to do. It is important to note that my python scripts contain command-line argparse arguments for it to run, for example:
python San_cable_test.py -deviceIP 172.1.1.1 -deviceUsername myUsername -devicePassword myPassword
So far I have created a top-level python file that is set up to call two python scripts to start with that the user can enter. However, when I run the program and select one of the options and get the user arguments, I get a
error: unrecognized arguments:
I tried it two different ways and I'll show the tracebacks:
usage: San_cable_test.py [-h] [-deviceIP DEVICEIP]
The name of this script is: San_cable_test.py
[-deviceUsername DEVICEUSERNAME]
[-devicePassword DEVICEPASSWORD]
San_cable_test.py: error: unrecognized arguments: 172.1.1.1 myUsername myPassword
and
usage: San_cable_test.py [-h] [-deviceIP DEVICEIP]
[-deviceUsername DEVICEUSERNAME]
The name of this script is: San_cable_test.py
[-devicePassword DEVICEPASSWORD]
San_cable_test.py: error: unrecognized arguments: -deviceIP 172.1.1.1 -deviceUsername myUsername -devicePassword myPassword
This is my first time using the subprocces library and I don't know if I'm calling these scripts right. The problem is that these scripts are run in the command line using argparse, so that's the issue. Unfortunately I am using 2.7.16 because of this weird company thing and I've been trying to get my managers to know that 2.7 is going to be unsupported soon but that's not relevant as of now. Here is the important part of my code. I really appreciate the help!
def runMain():
scriptName = os.path.basename(__file__)
print("The name of this script: " + scriptName + "\n")
scriptPurpose = 'This script is the top-level module that can invoke any script the user desires !\n'
while True:
optionPrinter()
user_input = input("Please select an option for which your heart desires...\n")
switch_result = mySwitch(user_input)
if switch_result == "our_Switch":
deviceIP = raw_input("Enter the IP address for the device")
deviceUsername = raw_input("Enter the username for the device")
devicePassword = raw_input("Enter the password for the device")
subprocess.call(['python', 'our_Switch.py', deviceIP, deviceUsername, devicePassword])
elif switch_result == "San_cable_test":
deviceIP = raw_input("Enter the IP address for the device")
deviceUsername = raw_input("Enter the username for the device")
devicePassword = raw_input("Enter the password for the device")
subprocess.call(['python', 'San_cable_test.py', deviceIP, deviceUsername, devicePassword])
else:
print("Exiting the program now, have a great day !\n")
sys.exit(-1)
if __name__ == '__main__':
Here is the an example of argparse being used in one of the scripts
def runMain():
scriptName = os.path.basename(__file__)
print("The name of this script is: " + scriptName)
scriptPurpose = 'This script enables and disables the SAN switches'
parser = argparse.ArgumentParser(description=scriptPurpose, formatter_class=RawTextHelpFormatter)
parser.add_argument("-deviceIP", help="Target device IP address", type=str)
parser.add_argument("-deviceUsername", help="Target device username", type=str)
parser.add_argument("-devicePassword", help="Target device password", type=str)
args = parser.parse_args()
if args.deviceIP is None:
print("The device IP parameter is blank\n")
else:
deviceIP = args.deviceIP
if args.deviceUsername is None:
print("The device userName parameter is blank\n")
else:
deviceUsername = args.deviceUsername
if args.devicePassword is None:
print("The device password parameter is blank\n")
else:
devicePassword = args.devicePassword
print("**********************\n")
print (deviceIP + " " + deviceUsername + " " + devicePassword)
print("**********************\n")
print("This script allows the user to enable and disable ports on a SAN switch to see how it behaves\n")
print("Checking to see if the SAN switch is pingable\n")
test_ping = canPing(deviceIP)
if test_ping:
print("The switch is pingable, let's proceed !\n")
else:
print("This device is not pingable unfortunately, sorry... : (\n")
sys.exit(-1)
sshConnection = connectToSSH(deviceIP, deviceUsername, devicePassword)
while True:
optionPrinter()
user_input = input("Select an option from the menu\n")
switch_result = mySwitch_function(user_input)
if switch_result == 'ShowPort':
portShow(sshConnection)
elif switch_result == 'SwitchShow':
switchShow(sshConnection)
elif switch_result == 'EnablePort':
enablePort(sshConnection)
elif switch_result == 'DisablePort':
disablePort(sshConnection)
elif switch_result == 'disableEnable':
disableEnableIteration(sshConnection)
else:
print("Program is exiting now, have a great day/night ! \n")
sys.exit(-1)
You're missing the option names before the parameters.
subprocess.call(['python', 'our_Switch.py', '-deviceIP', deviceIP, '-deviceUsername', deviceUsername, '-devicePassword', devicePassword])
However, it would probably be cleaner if you changed these other scripts into Python modules that you could simply import and call directly as functions, rather than running them as subprocesses.

i want to run my python program(not script) with start command which is a method in that python program file to be executed

Hi have python program in which a start method is defined, in start method i am calling a win32serviceutil.StartService(service) method to start a service, like
import os, platform, subprocess
try:
import win32serviceutil
except:
os.system("pip install pywin32")
os.system("pip install pypiwin32")
import win32serviceutil
OS = platform.system() #will get you the platform/OS
print("You are using ", OS)
if __name__=='__main__':
service = 'WSearch'
def startByCLI():
cmd = 'net start '+service
os.system(cmd)
def startByPython():
# subprocess.check_output(["sc", "start", service], stderr=subprocess.STDOUT)
win32serviceutil.StartService(service)
if OS=='Windows':
try:
output = startByPython()
except subprocess.CalledProcessError as e:
print(e.output)
print(e.returncode)
#os.system('python test2.py')
subprocess.call("python ./install.py asadmin", shell=True)
startByCLI()
so what i actually want is i want to run the start method from command promt like this
python ./myfile.py startByPython
and it will trigger the startByPython method in myfile.py
many thanks in advance
Hey all thanks for your attention,
i wanted to run my file.py file with argument from command line like:
$ /usr/bin/python myfile.py start
i got the solution which is
def main():
# read arguments from the command line and
# check whether at least two elements were entered
if len(sys.argv) < 2:
print "Usage: python aws.py {start|stop}\n"
sys.exit(0)
else:
action = sys.argv[1]
if action == "start":
startInstance()
elif action == "stop":
stopInstance()
else:
print "Usage: python aws.py {start|stop}\n"

Use argparse module with argument for a function

I'm trying to execute my function play()
import argparse
from num2words import num2words
def play():
parser = argparse.ArgumentParser()
parser.add_argument("--b", default=100,type=int,help="b")
args = parser.parse_args()
for file in reversed(range(file)):
print(num2words(iteration) + " there are")
print(num2words(iteration) + " there are")
I keep running in python commandline:
>>> import myfile
>>> file.play()
but it keeps using the default=100, how can i specify the argument --b 10 for example?
Change your program to:
import argparse
from num2words import num2words
def play():
parser = argparse.ArgumentParser()
parser.add_argument("--b", default=100,type=int,help="b")
args = parser.parse_args()
for file in reversed(range(file)):
print(num2words(iteration) + " there are")
print(num2words(iteration) + " there are")
if __name__ == '__main__':
play()
and add all the missing code not shown in your question.
On the command line:
python my_file_name.py --b 10
The command line is not the interactive Python interpreter, i.e. the >>> prompt. Type exit() and then enter this line. The command line is the on Linux/Mac OS X for example the bash shell; on Windows the "DOS box".
For interactive work try:
>>> import sys
>>> sys.argv.extend(['--b', '10'])
>>> import myfile
>>> file.play()

Python usage not printing

im creating my first python "app" and im having problems with the args or lack of. If i execute the script with no arguments id expect a message stating usage, but instead im getting the following error
ERROR
unknown#ubuntu:~$ ./attack.py
Traceback (most recent call last):
File "./attack.py", line 60, in <module>
main(sys.argv[1:])
File "./attack.py", line 57, in main
print fread(FWORD)
File "./attack.py", line 19, in fread
flist = open(FWORD).readlines()
TypeError: coercing to Unicode: need string or buffer, NoneType found
CODE
#!/usr/bin/python
import sys, getopt, socket, fileinput, traceback
from Queue import Queue
from threading import Thread
def usage():
print "-h --help: help\n"
print "-f --file: File to read potential Sub-domains from.\n"
print "-p --PROXY: PROXY address and port. e.g http://192.168.1.64:8080\n"
print "-d --DOMAIN: DOMAIN to bruteforce.\n"
print "-t --thread: Thread count.\n"
print "-e: Turn debug on.\n"
sys.exit()
def fread(FWORD, *args):
flist = open(FWORD).readlines()
return flist
#def addcheck(fcontent):
def main(argv):
PROXY = None
DOMAIN = None
FWORD= None
try:
opts, argv =getopt.getopt(argv, "h:f:p:d:t:e",["help", "file=", "PROXY=", "DOMAIN=", "thread="])
except getopt.GetoptError as err:
print str(err)
usage()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
sys.exit()
elif opt in ("-f", "--file"):
FWORD = arg
elif opt in ("-p", "--PROXY"):
PROXY = arg
elif opt in ("-d", "--DOMAIN"):
DOMAIN = arg
elif opt in ("-t", "--thread"):
thread = arg
elif opt in '-e':
global _debug
_debug = 1
else:
usage()
sys.exit()
print fread(FWORD)
if __name__ == "__main__":
main(sys.argv[1:])
Ok thanks all for the comments and pointers. ZMO im going to go with docopt it looks clean and simple (simple just like me). Im not entire sure what i need to do to my old code so am uploading what i think i need to do. Can anyone tell me if this is the right direction?
What do i do with def main() now? and
#!/usr/bin/python
import sys, getopt, socket, fileinput, traceback
from Queue import Queue
from threading import Thread
def fread(FWORD, *args):
flist = open(FWORD).readlines()
return flist
def main(argv):
"""
Usage:
your_script.py [-f <file>] [-p <proxy>] [-d <domain>] [-t] [-v]
your_script.py -h | --help
Options:
-h --help Show this screen.
-f --file File to read potential Sub-domains from.
-p --proxy Proxy address and port. [default: http://127.0.0.1:8080]
-d --domain Domain to bruteforce.
-t --thread Thread count.
-v --verbose Turn debug on.
"""
# […] your code (NOT SURE WHAT CODE YOU MEAN?
if __name__ == "__main__":
from docopt import docopt
arguments = docopt(__doc__, version='0.1a')
print fread(FWORD)
geptopt is deprecated in modern python, you should use argparse instead. I personally prefer the 3rd party docopt
It's useless to give the sys.argv array as argument to main() because you import the sys module globally in your module context (and there are many other things you'd use from sys aside from argv). Your code would only make sense if you were doing the import in the if __name__ == "__main__", but then that would be not good python practice. A better thing to do is to actually parse the arguments and then give the returned NamedTuple as an argument to main().
Argparse example
# […] your code
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Your script.')
parser.add_argument('--file', '-f', metavar='FILE', dest='file', type=file,
help='File to read potential Sub-domains from.')
parser.add_argument('--proxy', '-p', dest='proxy', action='store',
help='Proxy address and port.', default='http://127.0.0.1:8080')
parser.add_argument('--domain', '-d', dest='domain', action='store',
help='Domain to bruteforce.')
parser.add_argument('--thread', '-t', dest='thread', action='store_true',
help='Thread count.')
parser.add_argument('--verbose', '-v', dest='verbose', action='store_true',
help='Turn debug on.')
args = parser.parse_args()
main(args)
docopt example
Your script presentation.
"""
Usage:
your_script.py [-f <file>] [-p <proxy>] [-d <domain>] [-t] [-v]
your_script.py -h | --help
Options:
-h --help Show this screen.
-f --file File to read potential Sub-domains from.
-p --proxy Proxy address and port. [default: http://127.0.0.1:8080]
-d --domain Domain to bruteforce.
-t --thread Thread count.
-v --verbose Turn debug on.
"""
# […] your code
if __name__ == "__main__":
from docopt import docopt
arguments = docopt(__doc__, version='Naval Fate 2.0')
main(arguments) # here using the parameter makes sense ;-)

To understand Python's optparse

Thank you for quack in pointing out the off-by-one!
The following code is my first attempt in writing code with Optparse.
How can you fix the following bug in getting the help by Optparse?
#!/usr/bin/env python
import sys
import os
from optparse import OptionParser
e = sys.argv[1]
b = sys.argv[2]
no = sys.argv[3]
def set_figu(figu):
sum = 777
return sum
def main():
usage = "Usage: negative_bin_base.py <eksponentti> <siirre> <figu>"
parser = OptionParser(usage)
parser.add_option("-h", "--help", dest="help",
help="get synopsis of parameters")
# print the output of the work-horse
print set_figu(no)
(options, args) = parser.parse_args()
if len(args) < 4:
parser.error("incorrect number of arguments")
if options.informative:
print "reading %s..." % options.help
if __name__ == "__main__":
main()
Example of wrong output with correct number of parameters
python negative_bin_base.py 13 13 332
Traceback (most recent call last):
File "negative_bin_base.py", line 37, in <module>
main()
File "negative_bin_base.py", line 26, in main
help="get synopsis of parameters")
File "/usr/lib/python2.6/optparse.py", line 1020, in add_option
self._check_conflict(option)
File "/usr/lib/python2.6/optparse.py", line 995, in _check_conflict
option)
optparse.OptionConflictError: option -h/--help: conflicting option string(s): -h, --help
Constructor for class optparse.OptionParser(...) has optional named parameter 'add_help_option', which defaults to 'True'. You will have to explicitly reject default help option and message, if you want to provide your own.
parser = OptionParser(usage, add_help_option=False)
The bug is that your arguments array includes the name of the script as sys.argv[0]. Thus your if is off-by-one:
# python sys.argv[0] sys.argv[1] sys.argv[2] sys.argv[3]
if len(sys.argv) < 4:
sys.exit(usage)
This should do what you require, based on your example above:
#!/usr/bin/env python
from optparse import OptionParser
def main():
usage = "Usage: negative_bin_base.py <eksponentti> <siirre> <figu>"
parser = OptionParser(usage)
(options, args) = parser.parse_args()
if len(args) != 3:
parser.error("incorrect number of arguments")
e = args[0]
b = args[1]
no = args[2]
# ...
if __name__ == "__main__":
main()
For using optparse here's what I normally do:
separate command line parsing from your main code base for better modularization.
(Put the processing right after "if __name__ == "__main__"")
Let optparse handle your help.
(Use parser.print_help())
Use the optparse constructs, if you don't like them just parse sys.argv yourself.
(use add_option to define your necessary options)
Here's how I would write your sample using the optparse library:
def main():
print 'Welcome to the main event!'
if __name__ == '__main__':
import optparse
parser = optparse.OptionParser()
parser.add_option("-e", "--eksponentti", dest="eksponentti",
help="This is help for <eksponentti>.",
default=None)
parser.add_option("-s", "--siirre", dest="siirre",
help="This is help for <siirre>.",
default=None)
parser.add_option("-f", "--figu", dest="figu",
help="This is help for <figu>.",
default=None)
(options, args) = parser.parse_args()
if options.eksponentti and options.siirre and options.figu:
main()
else:
print "ERROR -- Expected Arguments not given!"
parser.print_help()
Running this without the necessary options will give the following output:
(It's a little prettier than I can format it here...)
ERROR -- Expected Arguments not given! Usage: parm.py [options]
Options:
-h, --help show this help message and exit
-e EKSPONENTTI, --eksponentti=EKSPONENTTI This is help for <eksponentti>.
-s SIIRRE, --siirre=SIIRRE This is help for <siirre>.
-f FIGU, --figu=FIGU This is help for <figu>.

Categories