Search code examples
pythongetopt

Python getopt not setting correct value


It could be I'm completely misunderstanding the getopt module

I am trying to parse [--magic-m] to my program, but it does not set the correct field.

Part of Encrypt Function

def encrypt(filename, text, magic):
    if not magic is None:
        hash = pbkdf2_sha256.encrypt(magic, rounds=10000, salt_size=16)
        print pbkdf2_sha256.verify(magic, hash)
    try:
        d = load_image( filename )
    except Exception,e:
        print str(e)

Part of Load function

def load_image( filename ) :
    img = Image.open( os.path.join(__location__, filename) )
    img.load()
    data = np.asarray( img, dtype="int32" )
    return data

Main

if __name__ == "__main__":
    if not len(sys.argv[1:]):
        usage()
    try:
        opts,args = getopt.getopt(sys.argv[1:],"hedm:",["help", "encrypt", "decrypt", "magic="])
    except getopt.GetoptError as err:
        print str(err)
        usage()

    magic = None
    for o,a in opts:
        if o in ("-h","--help"):
            usage()
        elif o in ("-e","--encrypt"):
            to_encrypt = True
        elif o in ("-d","--decrypt"):
            to_encrypt = False
        elif o in ("-m", "--magic"):
            magic = a
        else:
            assert False,"Unhandled Option"

    print magic
    if not to_encrypt:
        filename    = sys.argv[2]
        decrypt(filename, magic)
    else:
        filename    = sys.argv[2]
        text        = sys.argv[3]
        encrypt(filename, text, magic)

I tried calling the program above like this:

[1] python stego.py -e test.jpeg lol -m h

or like this:

[2] python stego.py -e -m h test.jpeg lol

Output becomes:

[1] None

[2] lol
[2] True
[2] [Errno 2] No such file or directory: 'C:\\Users\\Educontract\\Steganography\\-m'

Whitout the option -m everything works fine


Solution

  • The colon should come after m to indicate that it requires an argument. You should also include an equals sign after the long option magic to indicate that it requires an argument.

    getopt.getopt(sys.argv[1:],"hedm:",["help", "encrypt", "decrypt", "magic="])
    

    You should put all your options before the arguments, as in your second example.

    python stego.py -e -m h test.jpeg lol
    

    If you print sys.argv, I think you'll find that sys.argv[2] and sys.argv[3] are not what you expect. I would fetch the arguments from args, rather than sys.argv.

    filename    = args[0]
    text        = args[1]
    

    Note that you may find it easier to use the argparse library instead of getopt. It isn't as strict about requiring options before arguments.