Forcing getopt to process a specific option first??

Discussion in 'Python' started by Dan Rawson, Sep 18, 2003.

  1. Dan Rawson

    Dan Rawson Guest

    Is there any way to force getopt to process one option first?? I'd like to be able to pass in the name of a
    configuration file for my application, then have the remaining command-line parameters over-ride the configuration file
    if they are present.

    For the moment, I'm restricted to 2.2 versions.

    TIA . . . .

    Dan
    Dan Rawson, Sep 18, 2003
    #1
    1. Advertising

  2. Dan> Is there any way to force getopt to process one option first?? I'd
    Dan> like to be able to pass in the name of a configuration file for my
    Dan> application, then have the remaining command-line parameters
    Dan> over-ride the configuration file if they are present.

    Not that I'm aware of. If the order of the remaining options doesn't
    matter, you might try splitting the argument list before the option which
    introduces your config file. For example, given this set of command line
    args:

    -f bar -o baz -c configfile -o bump -h

    locate the '-c' and use it to split the argument list, then swap the two
    pieces:

    >>> s = "-f bar -o baz -c configfile -o bump -h"
    >>> args = s.split()
    >>> args

    ['-f', 'bar', '-o', 'baz', '-c', 'configfile', '-o', 'bump', '-h']
    >>> index = args.index('-c')
    >>> index

    4
    >>> args[:index], args[index:]

    (['-f', 'bar', '-o', 'baz'], ['-c', 'configfile', '-o', 'bump', '-h'])
    >>> args = args[index:] + args[:index]
    >>> args

    ['-c', 'configfile', '-o', 'bump', '-h', '-f', 'bar', '-o', 'baz']

    Now pass that list to getopt.getopt().

    If the order of the remaining arguments does matter, you just split the
    argument list into three pieces, the part before rearranging:

    >>> args[:index], args[index:index+2], args[index+2:]

    (['-f', 'bar', '-o', 'baz'], ['-c', 'configfile'], ['-o', 'bump', '-h'])
    >>> args = args[index:index+2] + args[:index] + args[index+2:]
    >>> args

    ['-c', 'configfile', '-f', 'bar', '-o', 'baz', '-o', 'bump', '-h']

    Skip
    Skip Montanaro, Sep 18, 2003
    #2
    1. Advertising

  3. Dan Rawson

    Peter Otten Guest

    Dan Rawson wrote:

    > Is there any way to force getopt to process one option first?? I'd like
    > to be able to pass in the name of a configuration file for my application,
    > then have the remaining command-line parameters over-ride the
    > configuration file if they are present.


    The easiest solution would be to make the config file the mandatory first
    argument of the command line and then call

    getopt.getopt(sys.argv[2:], options)

    Below is another approach, that might fit your needs:

    import getopt

    #sample args
    args = ["-c", "config.txt", "-r", "-i", "specialin.txt"]

    options, args = getopt.getopt(args, "c:ri:eek::")
    useroptions = dict(options)

    if "-c" in useroptions:

    #set defaults
    defaultoptions = {"-i": "defaultin.txt", "-o": "defaultout.txt"}

    del useroptions["-c"]

    #override defaults
    defaultoptions.update(useroptions)
    options = defaultoptions.items()

    print options

    Peter
    Peter Otten, Sep 18, 2003
    #3
  4. Dan Rawson

    Dan Rawson Guest

    Skip Montanaro wrote:
    > Dan> Is there any way to force getopt to process one option first?? I'd
    > Dan> like to be able to pass in the name of a configuration file for my
    > Dan> application, then have the remaining command-line parameters
    > Dan> over-ride the configuration file if they are present.
    >
    > Not that I'm aware of. If the order of the remaining options doesn't
    > matter, you might try splitting the argument list before the option which
    > introduces your config file. For example, given this set of command line
    > args:
    >
    > -f bar -o baz -c configfile -o bump -h
    >
    > locate the '-c' and use it to split the argument list, then swap the two
    > pieces:
    >
    > >>> s = "-f bar -o baz -c configfile -o bump -h"
    > >>> args = s.split()
    > >>> args

    > ['-f', 'bar', '-o', 'baz', '-c', 'configfile', '-o', 'bump', '-h']
    > >>> index = args.index('-c')
    > >>> index

    > 4
    > >>> args[:index], args[index:]

    > (['-f', 'bar', '-o', 'baz'], ['-c', 'configfile', '-o', 'bump', '-h'])
    > >>> args = args[index:] + args[:index]
    > >>> args

    > ['-c', 'configfile', '-o', 'bump', '-h', '-f', 'bar', '-o', 'baz']
    >
    > Now pass that list to getopt.getopt().
    >
    > If the order of the remaining arguments does matter, you just split the
    > argument list into three pieces, the part before rearranging:
    >
    > >>> args[:index], args[index:index+2], args[index+2:]

    > (['-f', 'bar', '-o', 'baz'], ['-c', 'configfile'], ['-o', 'bump', '-h'])
    > >>> args = args[index:index+2] + args[:index] + args[index+2:]
    > >>> args

    > ['-c', 'configfile', '-f', 'bar', '-o', 'baz', '-o', 'bump', '-h']
    >
    > Skip
    >

    Thanks! Either this solution or the one Peter Otten proposed will work . . .

    Wow, two good solutions in an hour . . . .

    Dan
    Dan Rawson, Sep 18, 2003
    #4
  5. Dan Rawson

    Jeff Epler Guest

    Care for another solution?

    I'd simply do two passes over the argument list. This has an advantage
    over both the other alternatives proposed. First, it works if the user
    writes something like "-bccf" (equivalent to the arguments ["-b", "-c", "cf"]),
    and second it works with repeated options like [-a", "x", "-a", "y"].

    This doesn't work if something in the configuration file could affect
    the available set of commandline switches. There may be some other
    shortcoming I haven't considered yet, too.

    Jeff

    ########################################################################
    # Program
    import getopt

    def main(argv):
    args, rest = getopt.getopt(argv, "c:a:b")

    # First pass, parse any -c option
    for k, v in args:
    if k == "-c":
    print "Using config file", v

    # Next, parse the other options
    for k, v in args:
    if k == "-c": continue
    print "Processing switch", k, v


    print "Remaining positional arguments", rest
    argv = "-a x -bccf -a y ...".split()
    main(argv)

    ########################################################################
    # Output
    Using config file cf
    Processing switch -a x
    Processing switch -b
    Processing switch -a y
    Remaining positional arguments ['...']
    Jeff Epler, Sep 19, 2003
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Shapiro

    python and getopt and spaces in option

    David Shapiro, Jun 9, 2009, in forum: Python
    Replies:
    1
    Views:
    794
    Jorgen Grahn
    Jun 10, 2009
  2. Sunil
    Replies:
    5
    Views:
    317
    Bart Lateur
    Aug 14, 2003
  3. Sunil
    Replies:
    8
    Views:
    136
    Benjamin Goldberg
    Sep 2, 2003
  4. Perl Learner
    Replies:
    1
    Views:
    196
    Jim Keenan
    Jun 13, 2005
  5. hymie!
    Replies:
    1
    Views:
    131
    hymie!
    Dec 27, 2005
Loading...

Share This Page