python and sys.argv - python

if len(sys.argv) < 2:
sys.stderr.write('Usage: sys.argv[0] ')
sys.exit(1)
if not os.path.exists(sys.argv[1]):
sys.stderr.write('ERROR: Database sys.argv[1] was not found!')
sys.exit(1)
This is a portion of code I'm working on. The first part I'm trying to say if the user doesn't type python programname something then it will exit.
The second part I'm trying to see if the database exists. On both places I'm unsure if I have the correct way to write out the sys.argv's by stderr or not.

BTW you can pass the error message directly to sys.exit:
if len(sys.argv) < 2:
sys.exit('Usage: %s database-name' % sys.argv[0])
if not os.path.exists(sys.argv[1]):
sys.exit('ERROR: Database %s was not found!' % sys.argv[1])

In Python, you can't just embed arbitrary Python expressions into literal strings and have it substitute the value of the string. You need to either:
sys.stderr.write("Usage: " + sys.argv[0])
or
sys.stderr.write("Usage: %s" % sys.argv[0])
Also, you may want to consider using the following syntax of print (for Python earlier than 3.x):
print >>sys.stderr, "Usage:", sys.argv[0]
Using print arguably makes the code easier to read. Python automatically adds a space between arguments to the print statement, so there will be one space after the colon in the above example.
In Python 3.x, you would use the print function:
print("Usage:", sys.argv[0], file=sys.stderr)
Finally, in Python 2.6 and later you can use .format:
print >>sys.stderr, "Usage: {0}".format(sys.argv[0])

I would do it this way:
import sys
def main(argv):
if len(argv) < 2:
sys.stderr.write("Usage: %s <database>" % (argv[0],))
return 1
if not os.path.exists(argv[1]):
sys.stderr.write("ERROR: Database %r was not found!" % (argv[1],))
return 1
if __name__ == "__main__":
sys.exit(main(sys.argv))
This allows main() to be imported into other modules if desired, and simplifies debugging because you can choose what argv should be.

Related

How to check if the parameter exist in python

I would like to create a simple python script that will take a parameter from the console, and it will display this parameter. If there will be no parameter then I would like to display error message, but custom message not something like IndexError: list index out of range
Something like this:
if isset(sys.argv[1]):
print sys.argv[1];
else:
print "No parameter has been included"
if len(sys.argv) >= 2:
print(sys.argv[1])
else:
print("No parameter has been included")
For more complex command line interfaces there is the argparse module
in Python's standard library - but for simple projects taking just a couple parameters directly checking sys.argv is alright.
update as of 2019, the recomendation is to use the external library "click", as it provides very "Pythonic" ways of including complex documents in a way they are easily documented.
You can check the lenght
if len(sys.argv) > 1:
...
Or the try/except
try:
sys.argv[1]
except IndexError as ie:
print("Exception : {0}".format(ie))
import sys
try:
print sys.argv[1]
except IndexError:
print "No parameter has been included"
import sys
print sys.argv[0] # will print your file name
if len(sys.argv) > 1:
print sys.argv[1];
else:
print "No parameter has been included"
OR
import sys
try:
print sys.argv[1]
except IndexError, e:
print "No parameter has been included"
Just for fun, you can also use getopt which provides you a way of predefining the options that are acceptable using the unix getopt conventions.
import sys
import getopt
try:
opts, args = getopt.getopt(sys.argv[1:], "hvxrc:s:", ["help", "config=", "section="])
except getopt.GetoptError as err:
print ("Option error:", str(err))
opts=[]
for op , val in opts:
print ("option",op,"Argument",val)
if not opts:
print ("No parameter supplied")
In the above if an incorrect parameter is supplied all of the options are scrapped.
Examples of use would be:
python myprog.py -h
python myprog.py --help
python myprog.py -c123
python myprog.py --config=123
https://pymotw.com/2/getopt/
http://linux.about.com/library/cmd/blcmdl1_getopt.htm
without exception model using if else short hand, in single line we can read args
args = sys.argv
env = args[1:] and args[1] or None
username = args[2:] and args[2] or None
password = args[3:] and args[3] or None

How to dynamically import variables after executing python script from within another script

I want to extract a variable named value that is set in a second, arbitrarily chosen, python script.
The process works when do it manually in pyhton's interactive mode, but when I run the main script from the command line, value is not imported.
The main script's input arguments are already successfully forwarded, but value seems to be in the local scope of the executed script.
I already tried to define value in the main script, and I also tried to set its accessibility to global.
This is the script I have so far
import sys
import getopt
def main(argv):
try:
(opts, args) = getopt.getopt(argv, "s:o:a:", ["script=", "operations=", "args="])
except getopt.GetoptError as e:
print(e)
sys.exit(2)
# script to be called
script = ""
# arguments that are expected by script
operations = []
argv = []
for (opt, arg) in opts:
if opt in ("-o", "--operations"):
operations = arg.split(',')
print("operations = '%s'" % str(operations))
elif opt in ("-s", "--script"):
script = arg;
print("script = '%s'" % script)
elif opt in ("-a", "--args"):
argv = arg.split(',')
print("arguments = '%s'" % str(argv))
# script should define variable 'value'
exec(open(script).read())
print("Executed '%s'. Value is printed below." % script)
print("Value = '%s'" % value)
if __name__ == "__main__":
main(sys.argv[1:])
The value variable has been put into your locals dictionary by the exec, but was not visible to the compiler. You can retrieve it like this:
print("Value = '%s'" % locals()['value'])
I would prefer an import solution
Using locals() as #cdarke suggested yielded the correct result!
exec(open(script).read())
print("Executed '%s'. Value is printed below." % script)
print("Value = '%s'" % locals()['value'])
In case your import needs to be dynamic, you can use
impmodule = __import__("modulename") # no .py suffix needed
then refer to value via
impmodule.value
There are several ways to achieve the same results.
See the answers on this topic on SO

Running pylint programmatically with the function epylint.py_run

When trying to run epylint.py_run to lint a file I pass in the filename and command-line options as a string, as specified in the docs. The file gets analyzed but the command-line options I pass aren't being applied. How can I get the function to apply the options I'm passing?
There is a bug in epylint.Run which omit to give the options, hence your problem.
In your case you should rather use the lint(filename, options) function, where options should be passed as a list of strings).
There is a bug in epylint.Run. I've submitted an issue. This should work:
def Run():
if len(sys.argv) == 1:
print("Usage: %s [options] <filename or module>" % sys.argv[0])
sys.exit(1)
elif not osp.exists(sys.argv[-1]):
print("%s does not exist" % sys.argv[1])
sys.exit(1)
else:
sys.exit(lint(options=sys.argv[:-1], filename=sys.argv[-1]))

Python debug print the command

Folks
I am not very up with Python but have inherited a load of Python scripts
One of which is given me a issue in that I am not 100% sure what one line is running
What I need to do is print out the command line and its variables.
The line in question is
ldapModify(userdn, mods, uri=uri)
What I am hoping to see is something like
/usr/bin/ldapmodify xxxx cn=......
Can any kind soul help.
The Python ldap lib doesn't call on the ldap command line client, it binds directly to the underlying system ldap lib.
If what you want is to know the values of the args passed to ldapModify, it's quite simple: print them to sys.stderr :
import sys
try:
ldapModify(userdn,mods,uri=uri)
except Exception, e:
print >> sys.stderr, "oops, ldapModify failed with '%s'" % e
print >> sys.stderr, "userdns : '%s' - uri : '%s' - mods : '%s'" % (userdns, uri, mods)
# and reraise the error so you get the whole traceback
raise
Before the line in question, you could place a call to python's interactive debugger. Then you can print out the variables in question:
import pdb
pdb.set_trace()
ldapModify(userdn, mods, uri=uri)
At the (pdb) prompt you can print out the value of any or all of the variables.
Here's a link about the debugger.

Python script running in linux

I am having trouble trying to get this script to work. When I debug this code it will not read into the class or functions. The code will not execute properly. Has anyone know the problem here, Thanks
#!/home/build/test/Python-2.6.4
import os, subprocess
class mks_function:
sandbox="new_sandbox"
def mks_create_sandbox():
try:
retcode=call("si createsandbox" + "--no --hostname=bel --port=70 --user=user --password=1234 --populate --project=e:/project.pj --lineTerminator=lf new_sandbox", shell=True)
if retcode < 0:
print >>sys.stderr, "Child was terminated by signal", -retcode
else:
print >>sys.stderr, "Child returned", retcode
except OSError, e:
print >>sys.stderr, "Execution failed:", e
print "sandbox retVal="+retcode
print "Creating a new sandbox called "+sandbox+" "
###############################################################
Few things to check your code
call should be subprocess.call
better use full path when you call for example, /usr/bin/si createsandbox, you can check with which si in shell
instead of concatenating the commands "si createsandbox" + "--no ...", please use list ["/usr/bin/si","createsandbox --no ..."]
you didn't import sys, but using it
sandbox should be self.sandbox and def mks_create_sandbox(): should be def mks_create_sandbox(self):
Use an IDE for example Ulipad.
Try put as the first line:
#!/usr/bin/env python
If you really need specific version of Python, setup your environment before running.
Possible problems:
your code is never executed (it's like you define the class only). Use it in the file (names are misleading):
if __name__ == '__main__':
myObject = mks_function()
show us how are you executing the code? Have you changed the permissions to be able to run the script?
chmod +x filename.py
or are you trying to start it as:
python filename.py

Categories