command line arguments processing: an ugly lpr wrapper

Beni Cherniavsky cben at techunix.technion.ac.il
Mon Mar 17 04:21:41 EST 2003


On 2003-03-16, morden wrote:

> I want the users of the script identify themselves with -B option
> (for logging) and pass the remaining arguments to lpr.
> What I came up with looks rather ugly:
>
> by="?"
> next = 0
> new_arg = []
> for arg in sys.argv:
> 	if next:
> 		by = arg
> 		next = 0
> 	else:
> 		if arg == "-B":
> 			next = 1
> 		else:
> 			new_arg.append(arg)
> ...
> # log "by" someplace
> ...
> os.execv("/usr/bin/lpr", new_arg)
>
> # should I exit(os.execv("/usr/bin/lpr", new_arg)) instead?
>
> So, my question is:
> how to make the code a bit less igly
> and make it take arguments in format -Bfoo in addition to -B foo?
>
Use getopt or optparse.  It will be more correct:

* "-B" might be a value supplied to some option and it should not be
  mistaken for an option in such a case (to handle these subtleties
  you will have to explain the whole lpr syntax to getopt/optparse).

* "-xB foo" where "-x" is another option that takes no arguments will
  be handled.

* You will have a chance to detect command line errors in your script
  instead of lpr, which might be useful to you (or might not).

Beyond that, the main ugly thing in your code is the `next` flag.
There is a neat trick for coding such loops: create the iterator
manually, so that you can fetch values with ``.next()`` and the for
loop will not see them:

# Untested but should work...
by="?"
new_args = []
args = iter(sys.argv)
for arg in args:  # you share the iterator with the for loop!
    if arg.startswith("-B"):
        by = arg[2:]
        if not by:
            by = args.next()  # here is the trick
    else:
        new_args.append(arg)

--help'ly y'rs
    Beni Cherniavsky <cben at tx.technion.ac.il>




More information about the Python-list mailing list